Bash脚本无效空间标志

时间:2016-07-26 14:24:31

标签: linux bash shell

我的目标是在目录中为最后修改的文件选择秒数。

我的名字中有空格的目录,希望用脚本stat。使用终端我只需使用:

sudo stat -c %Y /var/www/pre/data/jko/files/My\ Files

并且完美无缺。 在我的bash脚本中,我从目录/var/www/pre/data/jko/files/逐个读取文件(这是在while循环中)

touch tempFile.txt
#ls sort by last modified date
sudo ls -rt /var/www/pre/data/$line/files/ > tempFile.txt 
# read newest file
outputFile=$(tail -1 tempFile.txt) 
# replace all spaces with "\ " sign
outputFile=$(echo ${outputFile// /"\ "})
outputDirectoryToFile=/var/www/pre/data/$line/files/$outputFile
echo $outputDirectoryToFile
expr `sudo date +%s` - `sudo stat -c %Y $outputDirectoryToFile`

如果我用bash script.sh我的

来解雇这个脚本
/var/www/pre/data/jko/files/My\ Files //line from echo
stat: cannot stat '/var/www/pre/data/jko/files/My\': No such file or directory
stat: cannot stat 'Files': No such file or directory
expr: syntax error

或者可能有更简单的解决方案

2 个答案:

答案 0 :(得分:6)

正确,有效地在目录中找到最新文件

{ read -r -d ' ' mtime && IFS= read -r -d '' filename; } \
  < <(find /directory -type f -printf '%T@ %p\0' | sort -z -r -n)

...将把shell变量mtime中最近修改过的文件的时间(以秒为单位),以及shell变量filename中该文件的名称。

此外,它甚至可以用于具有令人惊讶或故意恶意名称的文件 - 名称中带有换行文字的文件名,带有圆形字符的文件名等。我对这个成语及其工作原理有更完整的解释{{3 }}

为什么您的原始代码无效

现在,原始代码出了什么问题?简而言之:字面引号不能替代句法引号。让我们进入这意味着什么。

/var/www/pre/data/jko/files/My\ Files中,反斜杠是 syntactic :它的shell语法。运行stat /var/www/pre/data/jko/files/My\ Files时,结果是一个如下所示的系统调用:

execv("/usr/bin/stat", "stat", "/var/www/pre/data/jko/files/My Files")

注意反斜杠如何消失?这是因为shell在解析字符串时会消耗它。

以下所有完全相同

# each of these assigns the same string to the variable named s
s=Hello\ World
s=Hello" "World
s='Hello World'

......他们可以扩展如下:

# this passes the *exact* contents of that variable as an argument to stat, and thus tries
# to stat a file named Hello World (no literal quotes in the name):
stat "$s"

在上面,引号再次是 syntactic - 它们告诉shell不要将变量扩展的结果拆分成多个单独的单词或将其评估为glob - 不是 literal ,在这种情况下,它们会作为参数的一部分传递给stat

那么,当你运行s=${s// /'\ '}时会发生什么?您将文字反斜杠放入数据中。

此后:

s="Hello World"
s=${s// /'\ '}    # change string to 'Hello\ World'
stat "$s"         # try to stat a file named 'Hello\ World', with the backslash 

如果在扩展中省略语法双引号会怎样?它更加丑陋:

s="Hello World"
s=${s// /'\ '}    # change string to 'Hello\ World'
stat $s           # try to stat a file named 'Hello\', and a second file named 'World'

那是因为不带引号的扩展并没有贯穿所有shell解析步骤;它只进行场分裂和全局扩展。

答案 1 :(得分:1)

如果路径包含空格,请引用它们以避免出现问题:

touch tempFile.txt
sudo ls -rt "/var/www/pre/data/$line/files/" > tempFile.txt //ls sort by last modified date
outputFile=$(tail -1 tempFile.txt) // read newest file
outputDirectoryToFile="/var/www/pre/data/$line/files/$outputFile"
echo $outputDirectoryToFile
expr `sudo date +%s` - `sudo stat -c %Y "$outputDirectoryToFile"`