Как отобразить команды оболочки при их выполнении

В сценарии оболочки, как я повторяю все вызванные команды оболочки и раскрываю имена любых переменных?

Например, с учетом следующей строки:

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

Выход выглядит следующим образом:

введите описание изображения здесь