2014-06-22 51 views
2

我想写我的第一个shell脚本。我写的代码必须在特定数据库被修改时执行。数据库驻留在我有一个安装点的Windows服务器上。这里是我迄今为止编写的脚本:Bash脚本不访问路径中的空格文件

#!/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声明是否成功。

这是我的文件1的LS:

[email protected] ~/scripts $ ls -l file1 
-rw-r--r-- 1 pi pi 0 Jun 20 10:27 file1 

这是数据库中的LS:

[email protected] ~/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 

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

[email protected] ~/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 
[email protected] ~/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 

条件语句工程完全按照我期望的那样。不幸的是,当我改变测试以使用包括空格的路径时,它再次失败。这太令人沮丧了!我也尝试过使用符号链接,但同样的问题发生。

好的,所以我是堆栈溢出新手,所以我不明白这是如何标记为重复和回答?正如我在上面的更新中解释的那样,删除对代字号的所有引用使得无差别,此问题有没有任何与代字符扩展有关,如您在上面更新的代码中看到的。

如果您还没有完全阅读和理解该问题,请不要标记为已回答的问题。

+0

您是否正在运行Ubuntu(或其衍生版)? –

+3

您正在引用波浪号。别。 –

+0

感谢您的回复。我在Raspberry Pi上运行Raspbian。 –

回答

0

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

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


此外,我会写第一行:

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

它不会使任何材料的差异,但它(IMO)整洁。

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

+0

我刚刚尝试从头重新输入整个脚本,避免任何形式的复制和粘贴。我仍然得到同样的错误,所以我不相信有任何错误的空间,标签等。我也同意第二点让阅读代码更容易。我曾尝试过所有可能的排列方式,但恐怕结果没有什么不同。 –

+0

在这种情况下,您必须在将目录列表复制到问题中时犯了错误,因为它在那里有两个空格。 –

+0

你能告诉我确切的地方有2个空格吗?我又看了一遍,看不到任何双间距。如果你指的是'ls'输出,那么也许这是一个粘贴错误,但我不能在实际的shell脚本中找到任何可能导致问题的双倍间距谢谢。 –

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 
+0

感谢您的回复。我试着重新编写整个脚本,这次彻底清除了代字号的引号,以尽可能简化事情。不幸的是,if语句仍然失败:( –

+0

@ user3746802向我显示了你正在使用的if语句(以及包含所有相关变量赋值的更新代码),并向我展示了一个'readlink -f'给fname \ w \ spaces.txt你例如'readlink -f fname \ w \ spaces.txt'这将为文件提供完整的路径,所以我们可以验证你的设置 –

+0

在引号之外移动波形符将允许它扩展,但是它也将允许它分词,从而打败了引用其他字符串的引用点,在这一点上,最好使用'“$ HOME/file with spaces.txt”'。 – kojiro

0

代替#/斌/我将它改为#!/ bin/bash,现在它工作得很完美。出于某种原因,破折号在某些条件下不支持-nt测试标志。当所有文件都存储在本地文件系统中时,它工作得很好,但拒绝正常访问网络共享。

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