如何使用相同的参数执行多个命令?

HoC*_*Co_ 18 command-line bash

我想知道是否可以在 Ubuntu 终端中进行连锁操作,例如:

action 1 on objectA . then action 2 on objectA 
Run Code Online (Sandbox Code Playgroud)

无需再重复 objectA 的名称。

例子:

touch file.js && openEditor "$1" 
Run Code Online (Sandbox Code Playgroud)

或类似的东西。

ste*_*ver 31

使用 bash History Expansion,您可以使用!#:neg引用当前命令行的第 n 个单词

$ touch foobar && ls -l !#:1
touch foobar && ls -l foobar
-rw-rw---- 1 steeldriver steeldriver 0 Jun 20 14:54 foobar

$ touch foo bar && ls -l !#:2
touch foo bar && ls -l bar
-rw-rw-r-- 1 steeldriver steeldriver 12 Jun 20 14:58 bar
Run Code Online (Sandbox Code Playgroud)

  • 您还可以指定[一系列单词](https://www.gnu.org/software/bash/manual/bash.html#Word-Designators):`touch foo bar && ls -l !#:1-2 ` (6认同)
  • @HoCo_ 在脚本中你应该提前知道参数是什么 - 例如你可以只做 `arg1=file.js; 触摸 "$arg1" && openEditor "$arg1"` (2认同)

Seb*_*ark 13

对于常见用例,有一个方便的快捷方式。在您的示例中,您正在执行以下操作:

$ touch file.js
$ openEditor <alt>+<.>
Run Code Online (Sandbox Code Playgroud)

在第二个命令中,诀窍是写openEditor(后面有一个空格)后跟Alt+ .。这将插入最后一个命令的最后一个参数,即file.js. (如果它Alt由于某种原因Esc不起作用,也应该起作用。)

由于通常“对象”确实是前一个命令的最后一个参数,因此可以经常使用。它很容易记住,并且可以快速集成到您直观使用的 shell 快捷方式中。

你可以用它做很多事情,这里有一篇关于可能性的深入文章:https : //stackoverflow.com/questions/4009412/how-to-use-arguments-from-previous-command

作为奖励,这不仅适用于 bash,而且适用于所有使用 libreadline 处理命令行输入的程序。

  • 您可以将其与 [digit 参数](https://askubuntu.com/a/1045169/507051) 结合使用,例如获取第二个参数按住 `Alt` 并按 `2。`(或 `Esc`、`2 `,`Esc`,`.`),要获得倒数第二个参数,按`Alt`+`-`,输入`2`,然后按`Alt`+`。`(或`Esc`,`-2` 、`Esc`、`.`)。 (2认同)

Ser*_*nyy 9

就默认的交互式 shellbash和脚本 shelldash而言,您可以使用$_来调用last command 的最后一个参数

$ echo "Hello World"; echo same "$_"
Hello World
same Hello World
Run Code Online (Sandbox Code Playgroud)

csh和 tcsh 有历史参考,特别是对于命令的最后一个字,你可以使用!$, 和个别参数 - !:<index>

~% echo foo bar
foo bar
~% echo !$
echo bar
bar

% echo bar baz
bar baz
% echo !:1
echo bar
bar
Run Code Online (Sandbox Code Playgroud)

通常,最好将任何内容分配给objectA变量,并在多个命令、循环等中使用它。或者,可以选择一个函数:

$ foo(){ echo "$@"; stat --print="%F\n" "$@";}
$ foo testdir
testdir
directory
Run Code Online (Sandbox Code Playgroud)

  • 此外,像往常一样,应该引用`$_`,否则它会像其他所有内容一样被拆分和合并。(我们只是在这里没有看到它,因为 `echo` 用一个空格连接了它的参数。)但是例如 `touch "hello there"; ls -l $_ ` 不起作用。 (3认同)

lef*_*out 5

我建议不要使用Steeldriver 的回答中给出的历史方法。这依赖于全局状态,而全局状态总是脆弱的。

更好的是使用适当的变量预先循环所有需要的命令:

$ for c in touch gedit; do $c foo.txt; done
Run Code Online (Sandbox Code Playgroud)

一般来说,有一点问题是,当发生故障时,Bash 不会中止,即这实际上的行为就像touch foo.txt; gedit foo.txt而不是链接到&&. 因此,为了安全起见,您可以添加break

$ for c in touch gedit; do $c foo.txt || break; done
Run Code Online (Sandbox Code Playgroud)