Как отобразить команды оболочки при их выполнении
В сценарии оболочки, как я повторяю все вызванные команды оболочки и раскрываю имена любых переменных?
Например, с учетом следующей строки:
ls $DIRNAME
Я хотел бы, чтобы скрипт запускал команду и отображал следующее
ls /full/path/to/some/dir
Цель состоит в том, чтобы сохранить журнал всех вызванных команд оболочки и их аргументов. Возможно, есть лучший способ создания такого журнала?
Ответы
Ответ 1
set -x
или set -o xtrace
расширяет переменные и печатает маленький знак + перед строкой.
set -v
или set -o verbose
не расширяет переменные перед печатью.
Используйте set +x
и set +v
чтобы отключить вышеуказанные настройки.
В первой строке скрипта можно поместить #!/bin/sh -x
(или -v
), чтобы иметь тот же эффект, что и set -x
(или -v
) позже в скрипте.
Выше также работает с /bin/sh
.
Смотрите вики bash-hackers по set
атрибутам и по отладке.
$ cat shl
#!/bin/bash
DIR=/tmp/so
ls $DIR
$ bash -x shl
+ DIR=/tmp/so
+ ls /tmp/so
$
Ответ 2
set -x
предоставит вам то, что вы хотите.
Вот пример оболочки script, чтобы продемонстрировать:
#!/bin/bash
set -x #echo on
ls $PWD
Это расширяет все переменные и печатает полные команды перед выходом команды.
выход:
+ ls /home/user/
file1.txt file2.txt
Ответ 3
Вы также можете переключить это для выбора строк в script, обернув их в set -x
и set +x
, например.
#!/bin/bash
...
if [[ ! -e $OUT_FILE ]];
then
echo "grabbing $URL"
set -x
curl --fail --noproxy $SERV -s -S $URL -o $OUT_FILE
set +x
fi
Ответ 4
Я использую функцию для эха, затем выполняю команду
#!/bin/bash
#function to display commands
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe echo hello world
Какие выходы
$ echo hello world
hello world
Edit:
Для более сложных команд и т.д. вы можете использовать eval:
#!/bin/bash
#function to display commands
exe() { echo "\$ ${@/eval/}" ; "[email protected]" ; }
exe eval "echo 'Hello World' | cut -d ' ' -f1"
Какие выходы
$ echo 'Hello World' | cut -d ' ' -f1
Hello
Ответ 5
Ответ shuckc для эхо-строк выбора имеет несколько недостатков: вы получаете также следующую команду set +x
, и вы теряете возможность проверить код выхода с помощью $?
, так как он перезаписывается set +x
.
Другой вариант - запустить команду в подоболочке:
echo "getting URL..."
( set -x ; curl -s --fail $URL -o $OUTFILE )
if [ $? -eq 0 ] ; then
echo "curl failed"
exit 1
fi
который даст вам выход, например:
getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed
Это повлечет за собой накладные расходы на создание новой подоболочки для команды.
Ответ 6
Другой вариант - поставить "-x" в верхней части вашего script, а не в командной строке:
$ cat ./server
#!/bin/bash -x
ssh [email protected]
$ ./server
+ ssh [email protected]
[email protected] password: ^C
$
(Недостаточно ответов, чтобы прокомментировать выбранный ответ.)
Ответ 7
Согласно TLDP Bash Руководство для начинающих: Глава 2. Создание сценариев написания и отладки
2.3.1. Отладка всего script
$ bash -x script1.sh
...
Теперь существует полноценный отладчик для Bash, доступный в SourceForge. Эти функции отладки доступны в большинстве современных версий Bash, начиная с 3.x.
2.3.2. Отладка на части (-ях) script
set -x # activate debugging from here
w
set +x # stop debugging from here
...
Таблица 2-1. Обзор установленных параметров отладки
Short | Long notation | Result
-------+---------------+--------------------------------------------------------------
set -f | set -o noglob | Disable file name generation using metacharacters (globbing).
set -v | set -o verbose| Prints shell input lines as they are read.
set -x | set -o xtrace | Print command traces before executing command.
...
В качестве альтернативы эти режимы могут быть указаны самим script, добавление необходимых параметров в объявление первой строки оболочки. Параметры можно комбинировать, как это обычно бывает с командами UNIX:
#!/bin/bash -xv
Ответ 8
Введите "bash -x" в командной строке перед именем bash script. Например, чтобы выполнить foo.sh, введите:
bash -x foo.sh
Ответ 9
Вы можете выполнить a bash script в режиме отладки с опцией -x.
Это будет отражать все команды.
bash -x example_script.sh
# Console output
+ cd /home/user
+ mv text.txt mytext.txt
Вы также можете сохранить параметр -x в script. Просто укажите параметр -x в shebang.
######## example_script.sh ###################
#!/bin/bash -x
cd /home/user
mv text.txt mytext.txt
##############################################
./example_script.sh
# Console output
+ cd /home/user
+ mv text.txt mytext.txt
Ответ 10
Кто-то выше размещен:
#!/bin/bash
#function to display commands
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
и это выглядит многообещающим, но я не могу для жизни понять, что он делает. Я googled и искал в man bash странице для "\ $" и "$ @" и ничего не нашел.
Я понимаю, что создается функция с именем "exec()". Я понимаю, что фигурные скобки обозначают начало и конец функции. Кажется, я понимаю, что полуколония обозначает "жесткий возврат" между многострочной командой, так что "{echo" \$$ @"; "$ @"; } 'становится, по существу:
{
echo "\$ [email protected]"
"[email protected]"
}
Может ли кто-нибудь дать мне краткое объяснение или где найти эту информацию, так как, очевидно, мой google-fu терпит неудачу?
(Без смысла запускать новый вопрос в старом потоке, моя цель - перенаправить вывод в файл. Метод set -x; [commands]; set + x будет работать для меня хорошо, но Я не могу понять, как эхо результатов в файл вместо экрана, поэтому я пытался понять этот другой метод в надежде, что смогу использовать меня очень плохое понимание перенаправления /pipe/tee/etc, чтобы сделать то же самое.)
Спасибо!
LATER EDIT:
С некоторым возиться, я считаю, что понял это. Здесь мой эквивалентный код для того, что мне нужно:
SCRIPT_LOG="\home\buddy\logfile.txt"
exe () {
params="[email protected]" # Put all of the command-line into "params"
printf "%s\t$params" "$(date)" >> "$SCRIPT_LOG" # Print the command to the log file
$params # Execute the command
}
exe rm -rf /Library/LaunchAgents/offendingfile
exe rm -rf /Library/LaunchAgents/secondoffendingfile
Результаты в файле logfile.txt выглядят примерно так:
Tue Jun 7 16:59:57 CDT 2016 rm -rf /Library/LaunchAgents/offendingfile
Tue Jun 7 16:59:57 CDT 2016 rm -rf /Library/LaunchAgents/secondoffendingfile
Только то, что мне нужно. Спасибо!
Ответ 11
Для zsh echo
setopt VERBOSE
и для отладки
setopt XTRACE
Ответ 12
Для csh
и tcsh
вы можете set verbose
или set echo
(или вы можете даже установить оба, но в большинстве случаев это может привести к некоторому дублированию).
Опция verbose
печатает в значительной степени именно то выражение оболочки, которое вы вводите.
Опция echo
более показательна для того, что будет выполнено через нерест.
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#verbose
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#echo
Special shell variables
verbose If set, causes the words of each command to be printed, after history substitution (if any). Set by the -v command line option.
echo If set, each command with its arguments is echoed just before it is executed. For non-builtin commands all expansions occur before echoing. Builtin commands are echoed before command and filename substitution, because these substitutions are then done selectively. Set by the -x command line option.
Ответ 13
Чтобы включить эхокомплексные команды, я использую функцию eval
plus Soth exe
для эха, а затем запустите команду. Это полезно для команд с каналами, которые в противном случае отображали бы только одну или только начальную часть команды.
Без eval:
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe ls -F | grep *.txt
Выходы:
$
file.txt
С eval:
exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe eval 'ls -F | grep *.txt'
Какие выходы
$ exe eval 'ls -F | grep *.txt'
file.txt
Ответ 14
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;
bash -x exampleScript.sh
Выход выглядит следующим образом:
![введите описание изображения здесь]()