在 BASH 中,当变量中的文件名包含单引号时,测试文件是否存在不起作用
In BASH, test if file exists does not work when filename in variable has single quotes
[更新]
1) 我有一个文件 (a.cfg),其中包含这样的行:
FILE;'/tmp/testfile';;;+;'Add this line';$;Y
2) 在我的脚本中,我逐行读取了这个文件:
while read line
do
...
done < a.cfg
3) 当一行被读取并且不为空时,我使用 IFS 拆分了该行:
IFS=';' read a b c d e f g h <<< $line
4) 为了确定,我回显了 $b 的内容。它 returns :
'/tmp/testfile'
包括单引号。
5) 接下来我想看看$b中存储的location是否存在:
if ! [ -e "$b" ]
then
echo "not found"
else
echo "found"
fi
未找到此 returns....
6) 当我根据提示执行 ls -l '/tmp/testfile'
时(同样,包括单引号),我得到:
-rw-r--r-- 1 root root 0 Jul 10 22:22 /tmp/testfile
(我有没有提到我正在以 root 身份执行所有这些操作?)
7) 我用几种方法尝试了上面的if语句,但结果还是一样:
if [ ! -e $b ]
if ! [ -e "$b" ]
if [[ ! -e $b ]]
if ! [[ -e $b ]]
那么,请告诉我哪里不对....
[结束更新]
我试图通过将变量的内容传递给 bash 的测试 -e 来测试文件是否存在。
变量看起来像这样:
FILE1='/etc/wherever/whatever'
当我这样做时:
[[ -e "$FILE1" ]]
$?等于1,提示找不到文件(以上路径为例....)
尝试了几个选项:
文件路径周围的双引号而不是单引号(变量是从文件中的一行获得的)
发现它只有在我将文件路径放入我阅读的文件中且没有任何引号时才有效。但是当使用其中包含空格的文件名时,这将是一个问题。
所以,澄清一下:
1) 文件包含一行一行读取的行
2) 使用 IFS 将行中的列拆分为单独的变量
3)一个变量是文件名,用单引号括起来
4) [[ -e $variable ]] 找不到文件。
请问正确的语法是什么?
你可以试试这个:
[ $(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
[更新]
1) 我有一个文件 (a.cfg),其中包含这样的行:
FILE;'/tmp/testfile';;;+;'Add this line';$;Y
2) 在我的脚本中,我逐行读取了这个文件:
while read line
do
...
done < a.cfg
3) 当一行被读取并且不为空时,我使用 IFS 拆分了该行:
IFS=';' read a b c d e f g h <<< $line
4) 为了确定,我回显了 $b 的内容。它 returns :
'/tmp/testfile'
包括单引号。
5) 接下来我想看看$b中存储的location是否存在:
if ! [ -e "$b" ]
then
echo "not found"
else
echo "found"
fi
未找到此 returns....
6) 当我根据提示执行 ls -l '/tmp/testfile'
时(同样,包括单引号),我得到:
-rw-r--r-- 1 root root 0 Jul 10 22:22 /tmp/testfile
(我有没有提到我正在以 root 身份执行所有这些操作?)
7) 我用几种方法尝试了上面的if语句,但结果还是一样:
if [ ! -e $b ]
if ! [ -e "$b" ]
if [[ ! -e $b ]]
if ! [[ -e $b ]]
那么,请告诉我哪里不对....
[结束更新]
我试图通过将变量的内容传递给 bash 的测试 -e 来测试文件是否存在。 变量看起来像这样:
FILE1='/etc/wherever/whatever'
当我这样做时:
[[ -e "$FILE1" ]]
$?等于1,提示找不到文件(以上路径为例....)
尝试了几个选项: 文件路径周围的双引号而不是单引号(变量是从文件中的一行获得的)
发现它只有在我将文件路径放入我阅读的文件中且没有任何引号时才有效。但是当使用其中包含空格的文件名时,这将是一个问题。
所以,澄清一下: 1) 文件包含一行一行读取的行 2) 使用 IFS 将行中的列拆分为单独的变量 3)一个变量是文件名,用单引号括起来 4) [[ -e $variable ]] 找不到文件。
请问正确的语法是什么?
你可以试试这个:
[ $(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