How to reuse the apt up
part of the apt update
and apt upgrade
commands to execute both commands in sequence in just one line without an alias.
Something like: apt up{date,grade}
.
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityHow to reuse the apt up
part of the apt update
and apt upgrade
commands to execute both commands in sequence in just one line without an alias.
Something like: apt up{date,grade}
.
The simple way ( and more efficient) is via for loop (on one line but here it's shown in multiple lines for clarity):
for i in {date,grade}; do
apt up${i}
done
The smart way is to make an alias in ~/.bashrc
for these two commands and forget about retyping it ever again:
alias upgrade=' sudo apt update && sudo apt upgrade'
The elaborate way is to do this:
$ echo sudo" "apt" "up{"date","grade"}" && " :
sudo apt update && sudo apt upgrade && :
See what's happening ? We're building a valid string of text to be run by shell. Now all you need to do is to use eval
instead of echo
. But eval
is generally not recommended in shell scripting and this command is much more convoluted and non portable than the for loop. Variation on the theme without eval (and shortest so far, but not efficient due to pipe and multiple commands echo
,two apt
,sudo
and sh
so lots of forking):
$ echo "apt "{update,upgrade}";"|sudo sh
We can also use set
to turn the desired sequence into positional parameters and just execute apt
with $1
and $2
args:
$ set {update,upgrade}; echo apt $1 && echo apt $2
apt update
apt upgrade
Or alternatively use for loop again, since it defaults to processing positional parameters if you don't specify a sequence in the for variable (sequence)
$ set {update,upgrade} ; for i; do echo apt $i ;done
apt update
apt upgrade
Using set
is a very common technique I see among professionals who work with shells a lot, and for a good reason - this is very portable and will work in /bin/sh
where you have no arrays or {a,b,c}
expansion. So POSIX-ly portable way would be set update upgrade ; for i; do echo apt $i ;done
. Additionally, this should be efficient.
Or we can go the while
loop route:
$ echo {date,$'\n',grade}|while read i;do echo apt up${i}; done
apt update
apt upgrade
Of course remember to run it without echo
for actual command execution to take place
for i in {date,grade}; do sudo apt up${i}; done
Oct 22, 2018 at 7:15
~/.bash_aliases
, too. This file should be automatically sourced by ~/.bashrc
.
Oct 22, 2018 at 7:36
apt
commands) with different arguments (update and upgrade), so I'll still say for loop is the way to go
Oct 22, 2018 at 7:38
for i in date grade; do
Oct 22, 2018 at 9:23
You can also use bash history expansion to get parts of the current command line and modify it:
$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
!#
is the current line:s/date/grade
is a modifier that substitutes date
with grade
Another simple option using xargs
instead of for
:
echo up{dat,grad}e | xargs -n1 apt
Test:
$ echo up{dat,grad}e | xargs -n1 echo apt
apt update
apt upgrade
However, I’d prefer a shell alias just like Sergiy because these “simple” ways are not simple enough to be actually useful.
printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%
although this is a bit longer
Oct 22, 2018 at 7:44
printf '%s'
is generally good practice since you can't escape it, e.g. with --help
or -e
.
printf '%s\0'
would be even better, xargs
has a flag to handle null terminated args
Oct 22, 2018 at 10:08
Create a function like this:
repeat() {
for suffix in "${@:2}";
do
eval "$1""$suffix";
done
}
Then you can run repeat 'apt up' {date,grade}
. This has the benefit of being reusable for totally different commands, although it's not saving you any typing for this one.
I'd certainly agree with some of the other answers that something like this is probably more useful:
alias apt-up='apt update && apt upgrade'
@muru's answer led me to read up on history expansion and I found another variant
$ sudo apt update
$ ^dat^grad^
^string1^string2^
is equivalent to !!:s/string1/string2/
, which takes the last command and replaces string1
with string2
.
I resuse the apt-get up
part of the command using the following key sequence:
Up ArrowBackspaceBackspaceBackspaceBackspace