Показывать команды без их выполнения
Я часто интерактивно петлю, например. мои файлы и хотите выполнить определенную операцию на всех из них, скажем, я хотел бы переименовать все файлы:
for file in $(ls); do mv "$file" "${file}_new"; done
Это прекрасно работает. Но прежде чем вызывать эту команду, я бы хотел посмотреть, что она на самом деле делает, поэтому я бы добавил эхо вперед
for file in $(ls); do echo mv "$file" "${file}_new"; done
он показывает мне все команды, которые он будет вызывать. Если я доволен ими, я удаляю echo
и выполняю его.
Однако, когда команды немного более тонкие, возможно, включая трубы или более одной команды, это больше не работает. Конечно, я мог бы использовать '
, поэтому специальные символы не интерпретируются, но тогда у меня нет расширения параметров. Я мог бы также избежать специальных символов, но это было бы очень утомительно.
Мой вопрос: какой лучший способ сделать это? Я прочитал в man bash
о опции -n
, которая выполняет "Чтение команд, но не выполняет их. Это может быть использовано для проверки оболочки script для синтаксических ошибок. Это игнорируется интерактивными оболочками". Это именно то, что мне нужно, но мне нужно это для интерактивной оболочки. Обратите внимание, что параметры -x
или -v
не помогают, так как он будет не только показывать команду, но и вызывать ее, а затем уже может быть уже слишком поздно.
Ответы
Ответ 1
Этот поток расскажет вам, почему опция показать команды вместо выполнения этих (так называемый "сухой" ) никогда не будет реализована для bash
.
Обратите внимание на ответ Эрик Блейк:
>
Мой вопрос в том, почему такой вариант не может быть предоставлен,
Маленькая мысль покажет, почему это никогда не будет реализовано. Какие будет ли такая опция выводиться для следующего:
if complex_command; then
foo=command1
else
foo=command2
fi
$foo args
В строке для $foo args
нет способа узнать, что расширяет $foo
если вы ранее не выполняли (а не только сканировали) complex_command
. Таким образом, нет возможности сушить пробег, результаты будут без запусков, но все работает, счетчик к цели сухого пробега.
Таким образом, вас может заинтересовать проект bashdb
, который использует bash, чтобы обеспечить интерфейс отладчика, где вы можете выполнить одноэтапный через bash script; это не то же самое, что сказать вам, что script, но он по крайней мере позволяет вам контролировать, сколько или мало из script выполняется.
Ответ 2
Нет опции для "сухого хода" как объясненной devnull, но есть простой способ:
debug=
#debug=echo
$debug mv "$file" "${file}_new"
Если вы удалите комментарий из второго задания (без изменения чего-либо еще), вы включите "сухой ход" для опасной команды mv
.
Более сложный подход состоял бы в том, чтобы проверить какое-либо условие (например, вариант командной строки):
debug=
if [[ ...enable dry run?... ]]; then
debug=echo
fi
Примечание. Пустое назначение необходимо, только если у вас есть опция -u
( "Устранить переменные как ошибку при замене." ).
Ответ 3
Существует github пакет, возможно, вот пример:
$ maybe rm file
> maybe has prevented rm file from performing 1 file system operations:
>
> delete /home/user/file
>
> Do you want to rerun rm file and permit these operations? [y/N]