首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash: ls的Subshell行为

Bash: ls的Subshell行为
EN

Stack Overflow用户
提问于 2017-10-26 21:17:35
回答 2查看 233关注 0票数 3

我想知道为什么我得不到相同的输出:

ls -1 -tF | head -n 1

echo $(ls -1 -tF | head -n 1)

我试图获取最后修改过的文件,但在子shell中使用它有时会得到多个文件,结果呢?

为什么会发生这种情况,如何避免?

EN

回答 2

Stack Overflow用户

发布于 2017-10-26 21:31:28

出现该问题的原因是,您正在为ls输出附加到文件名的shell特殊字符使用未加引号的子shell和-F标志。

-F,--分类

将指示符(*/=>@|之一)追加到条目

可执行文件以*作为后缀。

当你运行时

代码语言:javascript
复制
echo $(ls -1 -tF | head -n 1)

然后

代码语言:javascript
复制
$(ls -1 -tF | head -n 1)

将返回一个文件名,如果它恰好是一个可执行文件,同时也是另一个文件的前缀,那么它将同时返回这两个文件。

例如,如果您有

代码语言:javascript
复制
test.sh
test.sh.backup

然后它就会返回

代码语言:javascript
复制
test.sh*

当回显时,它会扩展为

代码语言:javascript
复制
test.sh test.sh.backup

引用子subshell可以防止这种扩展

代码语言:javascript
复制
echo "$(ls -1 -tF | head -n 1)"

返回

代码语言:javascript
复制
test.sh*
票数 6
EN

Stack Overflow用户

发布于 2017-10-26 21:30:40

我刚刚发现了错误:如果使用echo $(ls -1 -tF | head -n 1),文件全局机制可能会导致额外的匹配。

所以echo "$(ls -1 -tF | head -n 1)"会避免这种情况。

因为如果结果是一个可执行文件,那么它的末尾会包含一个*。

我试着在评论中放入为什么-F,但现在我决定把它放在这里:

我在我的.bashrc中添加了以下几行代码,以便获得列出上次修改的文件或目录的快捷方式:

代码语言:javascript
复制
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更改为该目录。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46955418

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档