关于shell:bash脚本错误可能与文件名长度有关(实际上我不知道是什么问题)

bash script error possibly related to length of filename (actually I don't know what's wrong)

本问题已经有最佳答案,请猛点这里访问。

这是我的问题代码的一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
fileList='fileList.txt'
#IFS=$'
'
while read filename
do
  echo listing"$filename"
  ls -ligG"$filename"
done <"$fileList"
echo"done."
#unset IFS
exit 0

输出是:

1
2
3
listing /some/long/path/README.TXT
ls: cannot access /some/long/pa
: No such file or directoryDME.TXT

请注意,ls会切断路径。 另请注意,路径/文件名的末尾将附加到错误消息中(在"无此类文件或目录"之后)。

我刚用这个路径测试了它,它仍然给出了错误:

/this/is/an/example/of/shorter/name.txt

有谁知道发生了什么? 我已经打了好几个小时了: - /

回应torek的回答,这里有更多信息:

首先,这是基于torek建议的修改过的脚本:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
fileList=/settings/Scripts/fileList.txt
while IFS=$'
'
read -r filename
do
  printf 'listing %q
'
"$filename"
  ls -ligG $filename
done <"$fileList"
echo"done."
exit 0

这是输出:

1
2
3
4
5
# ./test.sh
listing $'/example/pathname/myfile.txt
'

: No such file or directorypathname/myfile.txt
done.

请注意,仍有一些疯狂的事情发生。

这是文件。 它确实存在。

1
2
ls -ligG /example/pathname/myfile.txt
106828 -rwxrwx--- 1 34 Mar 28 00:55 /example/pathname/myfile.txt


基于异常行为,我将说该文件具有CRLF行终止符。您的文件名实际上有一个不可见的回车符附加到名称。在echo中,这不会显示,因为它只是跳转到第一列然后打印换行符。但是,ls尝试访问包含隐藏回车的文件,并在其错误消息中,回车导致错误消息部分覆盖您的路径。

要修剪这些字符,您可以使用tr

1
2
tr -d '
'
< fileList.txt > fileListTrimmed.txt

并尝试使用该文件。


嵌入式换行是一个线索:错误消息应该是ls: cannot access /some/long/path/README.TXT: No such file or directory(在"路径"中的"a"之后没有换行符)。即使发生了一些神秘的截断,冒号也应该在"路径"中的"a"之后发生。它没有,因此,字符串不是它看起来的样子。

尝试:

1
2
printf 'listing %q
'
"$filename"

在调用ls之前打印文件名。 Bash的内置printf具有%q格式,可引用有趣的字符。

我不确定注释掉的IFS设置的意图是什么。也许你想阻止read在空白处分裂?您可以将IFS=放在read前面,也可以使用read -r

1
2
while IFS=$'
'
read -r filename; do ...; done <"$fileList"