Повторно используйте части `apt up` команд` apt update` и `apt upgrade`, чтобы выполнить обе последовательности в одной строке

11

Как повторно использовать apt upчасть apt updateи apt upgradeкоманды для выполнения обеих команд в последовательности в одну строку без псевдонима.

Что - то вроде: apt up{date,grade}.

e200
источник
Какова будет цель достижения этого? Почему это может быть интересно / актуально?
ванадий
25
@vanadium Мы - пользователи Linux, пробуя бессмысленные вещи, мы можем изучить методы, которые могут быть применены позже к более сложным вещам, если бы никто из нас никогда этого не делал, давайте будем честными, никого из нас не было бы здесь
Даррен Х
1
@DarrenH Это то, что я действительно думал :-)
ванадий

Ответы:

19

Простой способ (и более эффективный) - цикл 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 &&  :

Видишь что происходит? Мы создаем правильную строку текста для запуска в оболочке. Теперь все, что вам нужно сделать, это использовать evalвместо echo. Но, evalкак правило, не рекомендуется в сценариях оболочки, и эта команда гораздо более сложна и непереносима, чем цикл for. Вариации на тему без Eval (и кратчайшим до сих пор, но не эффективно из - за трубы и несколько команд echo, два apt, sudoи 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является очень распространенной техникой, которую я вижу среди профессионалов, которые много работают с оболочками, и по уважительной причине - это очень переносимо и будет работать /bin/shтам, где у вас нет массивов или {a,b,c}расширений. Так что POSIX-ли портативный способ был бы 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фактического выполнения команды.

Сергей Колодяжный
источник
7
Просто сделайте цикл for в одной строке. for i in {date,grade}; do sudo apt up${i}; done
Видеонавт
3
Если вы предпочитаете, чтобы ваши файлы были аккуратными и аккуратными, вы также можете использовать псевдонимы ~/.bash_aliases. Этот файл должен быть автоматически получен ~/.bashrc.
francescop21
2
Я обновил свой ответ, возможно, тем, что вы хотите. Это однострочник, но я не думаю, что это облегчит задачу. Честно говоря, нет смысла делать это, когда вы хотите запустить две команды (да, это две aptкоманды) с разными аргументами (обновление и обновление), поэтому я все же скажу, что цикл - это путь,
Сергей Колодяжный,
1
Нет необходимости в расширении строки для заголовка цикла, просто назовите итерации:for i in date grade; do
rexkogitans
5
Такой псевдоним, очевидно, должен быть назван upgrate.
труба
14

Вы также можете использовать расширение истории bash, чтобы получить части текущей командной строки и изменить ее:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# текущая строка
  • :s/date/gradeэто модификатор , который заменяет dateсgrade
Мур
источник
6
Вы даже можете сохранить еще 2 символа, используя !#:s/dat/gradвместо этого
Дан
9

Еще один простой вариант использования xargsвместо for:

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

Тестовое задание:

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

Однако я бы предпочел псевдоним оболочки, такой как Сергей, потому что эти «простые» способы недостаточно просты, чтобы быть действительно полезными.

Melebius
источник
1
Очень хорошо. Вариация на тему может быть, printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%хотя это немного дольше
Сергей Колодяжный
printf '%s'как правило, хорошая практика, так как вы не можете избежать этого, например, с помощью --helpили -e.
yyny
@YoYoYonnY Да. Может printf '%s\0'быть, даже лучше, xargsесть флаг для обработки нулевых терминированных аргументов
Сергей Колодяжный
2

Создайте такую ​​функцию:

repeat() { 
    for suffix in "${@:2}";
    do
        eval "$1""$suffix";
    done
}

Тогда вы можете бежать repeat 'apt up' {date,grade}. Это имеет то преимущество, что его можно повторно использовать для совершенно разных команд, хотя это не спасает вас от набора текста для этой команды.

Я бы, конечно, согласился с некоторыми другими ответами, что что-то вроде этого, вероятно, более полезно:

alias apt-up='apt update && apt upgrade'
Мэтью Рид
источник
0

Ответ @ Муру привел меня к чтению истории расширения, и я нашел другой вариант

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^эквивалентно тому !!:s/string1/string2/, что принимает последнюю команду и заменяет string1на string2.

guntbert
источник
-2

Я повторно использую apt-get upчасть команды, используя следующую последовательность клавиш:

Up ArrowBackspaceBackspaceBackspaceBackspace

jdgregson
источник