[ -f /root/.bash_aliases ] || echo "$_"
给我]
我想/root/.bash_aliases
我也尝试过
[ -f /root/.bash_aliases ] || echo !:2
但它给了我以下结果
[ -f /root/.bash_aliases ] || echo /root/.bash_aliases
/root/.bash_aliases
我只想/root/.bash_aliases
答案1
这就是函数的用途:
print_if_not_regular() {
[ -f "$1" ] || printf '%s\n' "$1"
}
print_if_not_regular /root/.bash_aliases
有些 shell 喜欢es
或zsh
具有匿名函数:
(){[ -f "$1" ] || printf '%s\n' $1} /root/.bash_aliases # zsh
@ {[ -f $1 ] || printf '%s\n' $1} /root/.bash_aliases # es
我会避免使用$_
.例如,如果您有 DEBUG 陷阱,它就不再起作用。
$ bash -c 'trap ": \"\$((cmdcount+=1))\"" DEBUG; echo foo; echo "$_"'
foo
2
请注意,这!:n
不是最后一个命令的第 n 个参数,而是前一个命令行的第 n个词汇标记(存储到历史记录中的最后一行(甚至可能是多行))。例如,在
echo $(echo A B)
echo foo; echo !:1
它!:1
不会扩展为foo
(最后一个命令的最后一个参数),也不会扩展为 (上一个命令行的命令B
的最后一个参数),而是。在这里您需要输入:echo
echo
$(echo A B)
[ -f /root/.bash_aliases ] ||
echo !:2
也就是说,将其输入在单独的行中。在这里,即使当您输入第二行时历史记录行尚未完全完成,它也恰好(偶然)起作用。同样的技巧在(t)csh
(历史扩展的来源)中不起作用,也不起作用zsh
。
答案2
使用
test -f /root/.bash_aliases || echo "$_"
或者
test -f /root/.bash_aliases || printf '%s\n' "$_"
$_
将扩展到上一个命令的最后一个参数。在您的示例中,前一个命令是[
,它的最后一个参数是]
。
上面的最后一个命令是test
,它的最后一个参数是文件名。
test
和[
是相同的命令,但[
需要 a]
作为其最后一个命令行参数。在这种情况下,这就是很难使用它$_
来获取文件名的原因。
上述解决方案的优点是至少可以在bash
(除非您DEBUG
设置了陷阱)和中工作zsh
。
如果你的文件名在一个变量中,那么这样做就很简单了
[ -f "$name" ] || printf '%s\n' "$name"
或者
if [ ! -f "$name" ]; then
printf '%s\n' "$name"
fi
取决于您对if
语句和短路逻辑测试的偏好。