在BASH中,当变量中的文件名有单引号时,测试文件是否存在不起作用 [更新]
1) 我有一个文件(a.cfg),其中包含以下行:在BASH中,当变量中的文件名有单引号时,测试文件是否存在不起作用 [更新],bash,ifs,Bash,Ifs,1) 我有一个文件(a.cfg),其中包含以下行: FILE;'/tmp/testfile';;;+;'Add this line';$;Y 2) 在我的脚本中,我逐行读取此文件: while read line do ... done < a.cfg 包括单引号 5) 接下来,我想看看$b中存储的位置是否存在: if ! [ -e "$b" ] then echo "not found" else echo "found" fi 此返回未找到 6) 当我在提示符下执行ls-
FILE;'/tmp/testfile';;;+;'Add this line';$;Y
2) 在我的脚本中,我逐行读取此文件:
while read line
do
...
done < a.cfg
包括单引号
5) 接下来,我想看看$b中存储的位置是否存在:
if ! [ -e "$b" ]
then
echo "not found"
else
echo "found"
fi
此返回未找到
6) 当我在提示符下执行ls-l'/tmp/testfile'
时(同样包括单引号),我得到:
(我有没有提到我是以root的身份来做这一切?)
7) 我以多种方式尝试了上述if语句,但结果仍然相同:
if [ ! -e $b ]
if ! [ -e "$b" ]
if [[ ! -e $b ]]
if ! [[ -e $b ]]
所以,请告诉我我在想什么不对
[结束更新]
我试图通过将变量的内容传递给bash的test-e来测试文件是否存在。
变量如下所示:
FILE1='/etc/where/where'
当我这样做时:
[[ -e "$FILE1" ]]
美元?等于1,表示找不到该文件(上面的路径就是一个示例…)
尝试了几种选择:
文件路径周围的双引号而不是单引号(变量从文件中的一行获得)
发现只有当我将文件路径放在我读取的文件中而没有任何引号时,它才起作用。但当使用带有E空格的文件名时,这将是一个问题
因此,澄清一下:
1) 文件包含逐行读取的行
2) 行中的列使用IFS拆分为单独的变量
3) 一个变量是文件名,用单引号括起来
4) [[-e$variable]]找不到该文件
请问正确的语法是什么?您可以尝试以下方法:
[ $(ls "$file") == "$file" ]
还可以使用其他标志,如-r
或-x
您可以尝试以下方法:
[ $(ls "$file") == "$file" ]
还可以使用另一个标志,如
-r
或-x
这是因为字符串中有文字引号,它们不会被解释为shell脚本代码
考虑以下PHP代码:
$x="1+1";
echo 1+1; # Writes 2
echo $x; # Writes 1+1, not 2
它在Bash中的工作方式相同:
var="'myfile'"
[[ -e 'myfile' ]] # Checks for a file called myfile
[[ -e $var ]] # Checks for a filename with apostrophes in it, not myfile
您必须提取所需的确切文件名。由于您的文件名不包含撇号,您应该删除它们:
var="'myfile'"
var=${var//\'/} # Replace all apostrophes with nothing
if [[ -e $var ]]
then
echo "Exists"
fi
之所以会发生这种情况,是因为字符串中有文字引号,并且它们不会被解释为shell脚本代码 考虑以下PHP代码:
$x="1+1";
echo 1+1; # Writes 2
echo $x; # Writes 1+1, not 2
它在Bash中的工作方式相同:
var="'myfile'"
[[ -e 'myfile' ]] # Checks for a file called myfile
[[ -e $var ]] # Checks for a filename with apostrophes in it, not myfile
您必须提取所需的确切文件名。由于您的文件名不包含撇号,您应该删除它们:
var="'myfile'"
var=${var//\'/} # Replace all apostrophes with nothing
if [[ -e $var ]]
then
echo "Exists"
fi
我建议查看标记“testing”,因为这可能会导致与自动软件测试混淆,而自动软件测试正是该标记所代表的。您能否围绕此显示实际的bash代码,而不仅仅是片段?在
bash
中,该机制对我来说运行良好。如果使用双引号会发生什么情况:FILE1=“/etc/where/where”
?问题似乎在于读取/解析初始文件的方式。我怀疑在现实中你有FILE1=“”/etc/where/where'
。在这种情况下,只需去掉外部的单引号,然后像前面一样引用$FILE
。不管怎样,你的问题中缺少了这一部分(阅读/分析)。看起来效果不错。检查您的实际文件名。bash-4.3$f='a/b/c/d'bash-4.3$if[-e$f]];然后回音为真;根据要求,问题已更新。我建议查看“测试”标签,因为这可能会导致与自动化软件测试混淆,这就是这个标签的意思。你能展示一下你的bash代码吗,不仅仅是片段?在bash
中,该机制对我来说运行良好。如果使用双引号会发生什么情况:FILE1=“/etc/where/where”
?问题似乎在于读取/解析初始文件的方式。我怀疑在现实中你有FILE1=“”/etc/where/where'
。在这种情况下,只需去掉外部的单引号,然后像前面一样引用$FILE
。不管怎样,你的问题中缺少了这一部分(阅读/分析)。看起来效果不错。检查您的实际文件名。bash-4.3$f='a/b/c/d'bash-4.3$if[-e$f]];然后回音为真;根据请求,问题已被更新,这涉及到调用子shell,但效率不高。我会坚持原来的方法,但会修正引号(我怀疑@randomir是在某些东西上)。它还使用了一种非常糟糕的做法,即对任何编程的东西使用ls
的输出。这涉及到调用子shell,这并不太有效。我会坚持原来的方法,但会修正引号(我怀疑@randomir是在某些东西上)。它还使用了一种非常糟糕的做法,即对任何编程内容使用ls
的输出。