Запуск декількох команд в одному рядку в оболонці


388

Скажіть, у мене є файл, /templates/appleі я хочу

  1. покладіть його в два різні місця, а потім
  2. видалити оригінал.

Отже, /templates/appleбуде скопійовано в /templates/usedAND, /templates/inuse а потім після цього я хотів би видалити оригінал.

Чи cpнайкращий спосіб це зробити rm? Або є кращий спосіб?

Я хочу зробити це все в один рядок, тому я думаю, що це буде виглядати приблизно так:

cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple

Це правильний синтаксис?

Відповіді:


792

Ви використовуєте |(pipe) для перенаправлення виводу команди в іншу команду. Що ви шукаєте, це &&оператор, щоб виконати наступну команду, лише якщо попередня вдалася:

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple

Або

cp /templates/apple /templates/used && mv /templates/apple /templates/inuse

Для узагальнення (не вичерпно) операторів / сепараторів команд bash:

  • |труби (трубопроводи) стандартний вихід ( stdout) однієї команди на стандартний вхід іншої. Зауважте, що stderrвсе-таки переходить у стандартне призначення, що б там не сталося.
  • |&Труби та stdoutй stderrоднієї команди в стандартне введення інший. Дуже корисний, доступний у bash версії 4 та вище.
  • &&виконує команду праворуч &&лише у тому випадку, якщо попередня вдалася.
  • ||виконує команду праворуч, ||лише попередня помилка.
  • ;виконує команду праворуч ;завжди, незалежно від того, вдалася чи не вдалася попередня команда. Якщо set -eраніше не було викликано, що призводить bashдо помилки при помилці.

6
Отримано. Офіційна документація gnu.org/software/bash/manual/bash.html#Lists
flow2k

78

Чому б не cpрозташування 1, потім mvрозташування 2. Це допоможе "видалити" оригінал.

І ні, це не правильний синтаксис. |використовується для "трубопроводу" виводу з однієї програми та перетворення її на вхід для наступної програми. Що ви хочете ;, це відокремити кілька команд.

cp file1 file2 ; cp file1 file3 ; rm file1

Якщо вам потрібно, щоб окремі команди ОБОВ'ЯЗКОВО були успішними перед наступним запуском, тоді ви скористаєтесь &&:

cp file1 file2 && cp file1 file3 && rm file1

Таким чином, якщо будь-яка з cpкоманд не вдасться, rmзапуск не запуститься.


10

Зауважте, що cp A B; rm Aсаме так mv A B. Це теж буде швидше, оскільки вам не доведеться фактично копіювати байти (якщо припустити, що призначення знаходиться в тій же файловій системі), просто перейменуйте файл. Тож хочешcp A B; mv A C


7

Ще один варіант - набрати Ctrl+V Ctrl+Jв кінці кожної команди.

Приклад (замінити #на Ctrl+V Ctrl+J):

$ echo 1#
echo 2#
echo 3

Вихід:

1
2
3

Це виконує команди незалежно від того, якщо попередні не вдалися.

Такий же, як: echo 1; echo 2; echo 3

Якщо ви хочете зупинити виконання невдалих команд, додайте &&в кінці кожного рядка, крім останнього.

Приклад (замінити #на Ctrl+V Ctrl+J):

$ echo 1 &&#
failed-command &&#
echo 2

Вихід:

1
failed-command: command not found

У zshвас також можна використовувати Alt+Enterабо Esc+Enterзамість цьогоCtrl+V Ctrl+J


3

Спробуйте це..

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple


2

Використання труб мені здається дивним. У будь-якому випадку слід використовувати логічний andоператор Bash:

$ cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apples

Якщо cpкоманди не вдасться, rmзапуск не буде виконаний.

Або ви можете зробити більш розроблений командний рядок, використовуючи forцикл і cmp.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.