Выполнение нескольких команд в одной строке в оболочке
Скажем, у меня есть файл /templates/apple
, и я хочу
- поставьте его в двух разных местах, а затем
- удалите оригинал.
Итак, /templates/apple
будет скопирован в /templates/used
И /templates/inuse
и после этого Id хотел бы удалить оригинал.
Является ли cp
лучшим способом для этого, а затем rm
? Или есть лучший способ?
Я хочу сделать все это в одной строке, поэтому я думаю, что это будет выглядеть примерно так:
cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple
Является ли это правильным синтаксисом?
Ответы
Ответ 1
Вы используете |
(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
при ошибке.
Ответ 2
Почему бы не cp
перейти в местоположение 1, а затем mv
в местоположение 2. Это позаботится об "удалении" оригинала.
И нет, это не правильный синтаксис. |
используется для вывода "трубы" из одной программы и превращения ее в ввод для следующей программы. Вы хотите ;
, который разделяет несколько команд.
cp file1 file2 ; cp file1 file3 ; rm file1
Если вам требуется, чтобы отдельные команды ДОЛЖНЫ преуспеть до того, как можно будет запустить следующий, то вместо этого вы должны использовать &&
:
cp file1 file2 && cp file1 file3 && rm file1
Таким образом, если какая-либо из команд cp
не работает, rm
не будет выполняться.
Ответ 3
Обратите внимание, что cp A B; rm A
точно mv A B
. Это будет быстрее, так как вам не нужно фактически копировать байты (при условии, что пункт назначения находится в одной и той же файловой системе), просто переименуйте файл. Итак, вы хотите cp A B; mv A C
Ответ 4
Попробуйте это.
cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
Ответ 5
Другой вариант - набрать 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
Ответ 6
Использование труб кажется мне странным. В любом случае вы должны использовать логический оператор and
Bash:
$ cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apples
Если команды cp
выходят из строя, rm
не будет выполняться.
Или вы можете сделать более сложную командную строку, используя цикл for
и cmp
.
Ответ 7
Очень просто: Просто используйте &&
между каждой командой
Логика cp file1 file2 && cp file1 file3 && rm file1
EG 1:
cp /templates/apple /templates/used && mv /templates/apple /templates/inuse
EG 2:
cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
EDIT: Он работает для меня.