我正在尝试创建一个 bash 函数,它将使用一个简单的文件,例如
sample.txt
start=22 Mar 2016 10:00
end=22 Mar 2016 12:09
...并找到我在开始和结束指定的时间范围内安装到 /usr/local 的文件。
我最初创建的函数是:
function findInstalled () {
if [[ $# -ne 1 ]]; then
echo "[ERROR] Usage: findInstalled /path/to/file" ;
return 1;
fi
start=$( grep start $1 | cut -d'=' -f2 ) ;
end=$( grep end $1 | cut -d'=' -f2 ) ;
if [[ ! -z $start ]]; then
start="-newerct \"${start}\"" ;
fi
if [[ ! -z $end ]]; then
end="! -newerct \"${end}\"" ;
fi
echo find /usr/local $start $end -type f ;
find /usr/local $start $end -type f ;
}
..执行该函数会给出以下输出:
$ findInstalled /path/to/sample.txt
find /usr/local -newerct "22 Mar 2016 10:00" ! -newerct "22 Mar 2016 12:09" -type f
find: I cannot figure out how to interpret `"22' as a date or time
实际执行该命令会出现错误...cannot figure out how to interpret...
。但是,如果我复制并粘贴命令的回显版本,它会成功执行。 知道问题是什么吗? 请注意,我尝试过使用或不使用双引号和单引号的各种不同组合,但没有一个起作用。
通过执行以下操作,我已经使该功能正常工作,尽管不太按照我想要的方式工作:
function findInstalled () {
if [[ $# -ne 1 ]]; then
echo "[ERROR] Usage: findInstalled /path/to/file"
return 1;
fi
start=$( grep start $1 | cut -d'=' -f2 ) ;
end=$( grep end $1 | cut -d'=' -f2 ) ;
find /usr/local -newerct "$start" ! -newerct "$end" -type f ;
}
因此,使用这个,我已经成功地实现了我最初的目标,但我非常想知道为什么我原来的功能不起作用,或者它是否可能。
答案1
问题在于 shell 如何将行分成标记。它扩展$start
到-newerct "22 Mar 2016 10:00"
,然后在空格上分割单词。因此find
传递了以下参数:-newerct
、"22
、Mar
等,因此出现错误消息。man bash
状态:
扩展的顺序是:大括号扩展、波形符扩展、参数、变量和算术扩展以及命令替换(以从左到右的方式完成)、分词和路径名扩展。
我不确定它是否可以按照您想要的方式完成。您的第二个脚本更具可读性,但您必须确保变量不为空。也许你可以这样做:
find /usr/local ${start:+-newerct} "$start" ${end:+! -newerct} "$end" -type f ;