Bash脚本无法访问路径中包含空格的文件

时间:2014-06-22 04:44:31

标签: bash shell

我正在尝试编写我的第一个shell脚本。每当修改某个数据库时,必须执行我编写的代码。数据库驻留在我有挂载点的Windows服务器上。这是我迄今写的脚本:

#!/bin/sh

DB1=/mnt/reckon/"Point of Sale Lite 2013 Administrator"/QBPOS.PDB

ls -la "$DB1"

if [ "$DB1" -nt "~/scripts/file1" ]; then
  echo "Database has updated since last run"
  echo "Do some stuff here"
  touch file1
else
  echo "Database has not been updated"
fi

不幸的是,无论如何,脚本总是等于假。这是脚本开头的一个DB1用于调试,所以我可以看到DB1声明是否成功。

这是我的file1:

的ls
pi@mckinnonPi ~/scripts $ ls -l file1
-rw-r--r-- 1 pi pi 0 Jun 20 10:27 file1

这是数据库的ls:

pi@mckinnonPi ~/scripts $ ls -l /mnt/reckon/"Point of Sale Lite 2013     Administrator"/QBPOS.PDB
-rwxr-xr-x 1 root root 2048000 Jun 22 14:30 /mnt/reckon/Point of Sale Lite 2013     Administrator/QBPOS.PDB

正如您所看到的,数据库文件肯定比file1更新,但是如果我现在运行脚本,这就是我得到的:

pi@mckinnonPi ~/scripts $ ./fileage 
-rwxr-xr-x 1 root root 2048000 Jun 22 14:36 /mnt/reckon/Point of Sale Lite 2013 Administrator/QBPOS.PDB
Database has not been updated
pi@mckinnonPi ~/scripts $ 

很明显,DB1的声明正在工作,因为脚本中的ls命令成功,但由于某种原因文件年龄测试失败。我已经在这几天工作了,我尽可能多地研究,但已经碰到了一堵砖墙。非常感谢任何帮助。

谢谢!

  • 更新

我已经重写了脚本,以尽可能简化。当使用不包含空格的路径时,一切都按预期完成,因此当我运行此脚本时:

#!/bin/sh

# DB1=/mnt/qnap/Amarillo/Reckon/"Point of Sale Lite 2013 Administrator"/QBPOS.TXT
DB1=/tmp/test/file2
TF1=/home/pi/scripts/file1

ls -la "$DB1"
ls -la "$TF1"

if [ "$DB1" -nt "$TF1" ]; then
    echo "Database has been updated since last run"
    echo "Do some stuff here"
    touch /home/pi/scripts/file1
else
    echo "Database has NOT been updated"
fi

条件语句完全符合我的预期。不幸的是,当我更改测试以使用包含空格的路径时,它再次失败。这太令人沮丧了!我也尝试使用符号链接,但同样的问题也出现了。

好的,所以我是新的堆栈溢出,所以我不明白这是如何被标记为重复和回答?正如我在上面的更新中所解释的那样,删除所有对波形符的引用会使 NO DIFFERENCE ,这个问题与波形扩展没有没有,正如你在上面的更新代码。

如果您没有完全阅读并理解该问题,请不要将某些内容标记为已回答。

3 个答案:

答案 0 :(得分:2)

虽然其他人已经正确地注意到在引号内放置~会阻止shell扩展,但您可以自由地将其移到引号之外,然后扩展将正常工作。例如,以下工作正常:

#!/bin/sh

if [ -f ~/"fname w spaces.txt" ]; then
    printf "fname w spaces -- Found\n"
else
    printf "fname w spaces -- NOT Found\n"
fi

exit 0

在您的情况下,将if条件更改为以下内容并将~移到引号之外将允许扩展:

if [ "$DB1" -nt ~/"scripts/file1" ]; then

答案 1 :(得分:0)

从您提供的列表来看,我认为问题是您在“2013”​​之后有多个空格或TAB。如果在路径名中使用空格,Linux将不会使用巧妙的模糊匹配来尝试找出您/用户的意思。就Linux路径名而言,一个空间不同于两个......等等。

第二个问题(由@n.m发现!)是您引用以~开头的路径名。这将抑制~扩展到用户的主目录。


另外,我会把第一行写成:

    DB1="/mnt/reckon/Point of Sale Lite 2013 Administrator/QBPOS.PDB"

它没有任何重大差异,但它是(IMO)更整洁。

另外,我会尽量避免在Linux应用程序中使用或允许带有空格的路径名,因为它们往往很麻烦。在假设没有空格的情况下编写脚本的情况并不少见。 “玩得安全”最容易。

答案 2 :(得分:0)

而不是#!/ bin / sh我将它改为#!/ bin / bash,它现在正在完美运行。出于某种原因,dash在某些条件下不支持-nt test标志。当所有文件都存储在本地文件系统上时,它可以正常工作,但拒绝正常访问网络共享。

将shell更改为bash“#!/ bin / bash”解决了问题,现在脚本运行完美。感谢所有帮助过的人,我从这个小小的练习中学到了很多东西!