在BASH中,当变量中的文件名有单引号时,测试文件是否存在不起作用 [更新]

在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-

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-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
的输出。