Bash Unix:“;ls”;命令显示带有?延期后
我已经用Java编写了一个shell脚本(test.sh)。这个shell脚本实际上执行从一个文件到另一个文件的复制任务。在执行shell脚本之后,我从控制台打开目录并键入ls。它显示输出文件,其中包含?延期后 示例:foo.csvBash Unix:“;ls”;命令显示带有?延期后,bash,unix,shell,file,java,Bash,Unix,Shell,File,Java,我已经用Java编写了一个shell脚本(test.sh)。这个shell脚本实际上执行从一个文件到另一个文件的复制任务。在执行shell脚本之后,我从控制台打开目录并键入ls。它显示输出文件,其中包含?延期后 示例:foo.csv File execFile = new File(file); FileWriter fwFile; try { fwFile = new FileWriter(execFile); execFile.setExecutable(true);
File execFile = new File(file);
FileWriter fwFile;
try {
fwFile = new FileWriter(execFile);
execFile.setExecutable(true);
BufferedWriter bwFile = new BufferedWriter(fwFile);
bwFile.write(strOutput.substring(0, 2));
bwFile.write("\r\n");
bwFile.write("cd " + strOutput);
bwFile.write("\r\n");
bwFile.write("mkdir " + strOutput);
bwFile.write("\r\n");
bwFile.write(strUnixPath);
bwFile.write("\r\n");
bwFile.write("cd " + strWorkingPath + IPlatinumConstants.FS+"lib"+IPlatinumConstants.FS+"Unx");
bwFile.write("\r\n");
bwFile.write("echo Cut Src Start time %time%");
bwFile.write("\r\n");
bwFile.write("cp " + " \"" + strSourceFilePath + "\" \""
+ strOutput + "copy_A\"");
bwFile.write("\r\n");
我猜:
Java程序正在使用回车符+换行符来终止每一行。但是,Unix系统仅使用换行符\n
作为新行指示符。虽然终端可以理解回车符,但它对其他程序没有任何意义–就/bin/sh
解释器而言,它只是一个与其他任何程序一样的字符。这意味着\r
将成为脚本运行的每个命令的最后一个参数的一部分:
cd myoutput\r
mkdir myoutput\r
cd something/lib/something\r
echo Cut Src Start time %time%\r
cp "sourcefile" "myoutputcopy_A"\r
因此,最后一个命令总是创建在文件名称末尾带有回车符的文件,ls
像所有其他“不可打印”字符一样将其显示为问号。您可以使用ls-b
或ls-Q
看到这一点
要解决此问题,请在生成Unix shell脚本时仅使用
\n
。(或者,更好的是,不要生成shell脚本——而是在需要时编写接受参数的脚本。您也可以在Java程序本身中执行许多操作。)我实际上假设脚本甚至不在OP希望它去的地方。所以,相当混乱。为了检查这个答案是否反映了实际问题,OP可以运行ls | xxd
,并查看文件名十六进制表示法之后是否有0d
。@Ruslan-或者使用ls-b
@AFH哦,这甚至是cleanerIt,值得注意的是\n
可以合法地用作文件名中的字符,因此,将其用作文件名之间的分隔符注定会失败。ls
不应用于显示给最终用户以外的任何目的,仅用于人类消费。阅读说明(只是部分内容),了解尝试以编程方式使用ls
时可能出现的错误。您的程序也存在目前编写的shell注入安全性错误——如果目录的名称类似于foo$(rm-rf$HOME)bar
,猜猜当您针对写入的缓冲区调用shell时会发生什么?