我想知道为什么我得不到相同的输出:
ls -1 -tF | head -n 1
和
echo $(ls -1 -tF | head -n 1)
我试图获取最后修改过的文件,但在子shell中使用它有时会得到多个文件,结果呢?
为什么会发生这种情况,如何避免?
发布于 2017-10-26 21:31:28
出现该问题的原因是,您正在为ls输出附加到文件名的shell特殊字符使用未加引号的子shell和-F标志。
-F,--分类
将指示符(*/=>@|之一)追加到条目
可执行文件以*作为后缀。
当你运行时
echo $(ls -1 -tF | head -n 1)然后
$(ls -1 -tF | head -n 1)将返回一个文件名,如果它恰好是一个可执行文件,同时也是另一个文件的前缀,那么它将同时返回这两个文件。
例如,如果您有
test.sh
test.sh.backup然后它就会返回
test.sh*当回显时,它会扩展为
test.sh test.sh.backup引用子subshell可以防止这种扩展
echo "$(ls -1 -tF | head -n 1)"返回
test.sh*发布于 2017-10-26 21:30:40
我刚刚发现了错误:如果使用echo $(ls -1 -tF | head -n 1),文件全局机制可能会导致额外的匹配。
所以echo "$(ls -1 -tF | head -n 1)"会避免这种情况。
因为如果结果是一个可执行文件,那么它的末尾会包含一个*。
我试着在评论中放入为什么-F,但现在我决定把它放在这里:
我在我的.bashrc中添加了以下几行代码,以便获得列出上次修改的文件或目录的快捷方式:
function L {
myvar=$1; h=${myvar:="1"};
echo "last ${h} modified file(s):";
export L=$(ls -1 -tF|fgrep -v / |head -n ${h}| sed 's/\(\*\|=\|@\)$//g' );
ls -l $L;
}
function LD {
myvar=$1;
h=${myvar:="1"};
echo "last ${h} modified directories:";
export LD=$(ls -1 -tF|fgrep / |head -n $h | sed 's/\(\*\|=\|@\)$//g'); ls -ld $LD;
}
alias ol='L; xdg-open $L'
alias cdl='LD; cd $LD'因此,现在我可以使用L(或L5)来列出最后(最后5个)修改的文件。而不是目录。
使用L;jmacs $L,我可以打开我的编辑器来编辑它。传统上我使用我的别名lt='ls -lrt‘,但是我必须重新输入这个名字……
现在在mkdir之后...我使用cdl更改为该目录。
https://stackoverflow.com/questions/46955418
复制相似问题