重复使用 `apt update` 和 `apt upgrade` 命令中的 `apt up` 部分,只需一行即可按顺序执行两个命令

重复使用 `apt update` 和 `apt upgrade` 命令中的 `apt up` 部分,只需一行即可按顺序执行两个命令

如何重用和命令apt up的部分,以便在一行中按顺序执行两个命令,而无需别名。apt updateapt upgrade

就像是:apt up{date,grade}

答案1

简单的方法(并且更有效)是通过 for 循环(在一行中,但这里为了清楚起见以多行显示):

for i in {date,grade}; do
     apt up${i}
done

聪明的方法是给这两个命令创建一个别名~/.bashrc,这样就不用再重新输入了:

alias upgrade=' sudo apt update && sudo apt upgrade'

详细的做法是这样的:

$ echo sudo" "apt" "up{"date","grade"}" && " :
sudo apt update &&  sudo apt upgrade &&  :

看看发生了什么?我们正在构建一个有效的文本字符串以供 shell 运行。现在您需要做的就是使用eval而不是echo。但eval在 shell 脚本中通常不建议使用 ,并且此命令比 for 循环更复杂且不可移植。主题的变体没有 eval(迄今为止最短,但由于管道和多个命令echo,两个aptsudo以及sh大量分叉,效率不高):

$ echo "apt "{update,upgrade}";"|sudo sh

我们还可以使用set将所需的序列转换为位置参数,然后使用apt$1参数执行$2

$ set {update,upgrade}; echo apt $1 && echo apt $2
apt update
apt upgrade

或者再次使用 for 循环,因为如果你没有在中指定序列,它会默认处理位置参数for variable (sequence)

$ set {update,upgrade} ; for i; do echo apt $i ;done
apt update
apt upgrade

使用set是一种非常常见的技术,我经常在经常使用 shell 的专业人士中看到这种技术,原因很简单 - 这种技术非常便携,可以在/bin/sh没有数组或{a,b,c}扩展的情况下工作。因此,POSIX-ly 可移植方式将是set update upgrade ; for i; do echo apt $i ;done。此外,这应该是高效的。


或者我们可以走while循环路线:

$ echo {date,$'\n',grade}|while read i;do echo apt up${i}; done 
apt update
apt upgrade

当然,请记住,echo在实际命令执行之前不要运行它

答案2

您也可以使用 bash历史扩展获取当前命令行的部分内容并修改它:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !#是当前行
  • :s/date/gradedate是替代修饰符grade

答案3

另一个简单的选择是使用xargs而不是for

echo up{dat,grad}e | xargs -n1 apt

测试:

$ echo up{dat,grad}e | xargs -n1 echo apt
apt update
apt upgrade

不过,我更喜欢 shell 别名就像 Sergiy 一样因为这些“简单”的方法并不够简单,实际上并不实用。

答案4

@muru 的回答让我读到了历史扩展我发现了另一种变体

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^相当于!!:s/string1/string2/,它采用最后一个命令并替换string1string2

相关内容