Подтвердить что ты не робот

Echo, а затем запустите его? (Как сделать)

Есть ли способ получить bash в какой-то подробный режим, где, например, когда он запускает оболочку script, она отгоняет команду, которую она запускает, прежде чем запускать ее? То есть, чтобы можно было увидеть команды, которые были запущены (а также их вывод), похожие на вывод make?

То есть, если запустить оболочку script как

echo "Hello, World"

Мне нужен следующий вывод

echo "Hello, World"
Hello, World

В качестве альтернативы можно ли написать функцию bash под названием echo_and_run, которая выведет команду, а затем запустит ее?

$ echo_and_run echo "Hello, World"
echo "Hello, World"
Hello, World
4b9b3361

Ответ 1

Можно использовать bash printf в сочетании с спецификатором формата %q, чтобы избежать аргументов, чтобы сохранить пробелы:

function echo_and_run {
  echo "$" "[email protected]"
  eval $(printf '%q ' "[email protected]") < /dev/tty
}

Ответ 2

Вы можете сделать свою собственную функцию для команд echo до вызова eval.

Bash также имеет функцию отладки. После того, как вы set -x bash отобразите каждую команду перед ее выполнением.

[email protected]:~/dir$ set -x
[email protected]:~/dir$ ls
+ ls --color=auto
a  b  c  d  e  f

Ответ 3

Чтобы ответить на вторую часть вашего вопроса, вот функция оболочки, которая делает то, что вы хотите:

echo_and_run() { echo "$*" ; "[email protected]" ; }

Я использую что-то похожее на это:

echo_and_run() { echo "\$ $*" ; "[email protected]" ; }

который печатает $ перед командой (это похоже на приглашение оболочки и проясняет, что это команда). Я иногда использую это в сценариях, когда хочу показать некоторые (но не все) команды, которые он выполняет.

Как уже упоминали другие, он теряет кавычки:

$ echo_and_run echo "Hello, world"
$ echo Hello, world
Hello, world
$ 

но я не думаю, что есть хороший способ избежать этого; оболочка удаляет кавычки, прежде чем echo_and_run получит возможность их увидеть. Вы можете написать скрипт, который будет проверять наличие аргументов, содержащих пробелы и другие метасимволы оболочки, и добавлять кавычки по мере необходимости (которые все равно не обязательно будут совпадать с кавычками, которые вы фактически ввели).

Ответ 4

Чтобы добавить к другим реализациям, это мой основной шаблон script, включая разбор аргументов (что важно, если вы переключаете уровни детализации).

#!/bin/sh

# Control verbosity
VERBOSE=0

# For use in usage() and in log messages
SCRIPT_NAME="$(basename $0)"

ARGS=()

# Usage function: tells the user what up, then exits.  ALWAYS implement this.
# Optionally, prints an error message
# usage [{errorLevel} {message...}
function usage() {
    local RET=0
    if [ $# -gt 0 ]; then
        RET=$1; shift;
    fi
    if [ $# -gt 0 ]; then
        log "[$SCRIPT_NAME] ${@}"
    fi
    log "Describe this script"
    log "Usage: $SCRIPT_NAME [-v|-q]" # List further options here
    log "   -v|--verbose    Be more verbose"
    log "   -q|--quiet      Be less verbose"
    exit $RET
}

# Write a message to stderr
# log {message...}
function log() {
    echo "${@}" >&2
}

# Write an informative message with decoration
# info {message...}
function info() {
    if [ $VERBOSE -gt 0 ]; then
        log "[$SCRIPT_NAME] ${@}"
    fi
}

# Write an warning message with decoration
# warn {message...}
function warn() {
    if [ $VERBOSE -gt 0 ]; then
        log "[$SCRIPT_NAME] Warning: ${@}"
    fi
}

# Write an error and exit
# error {errorLevel} {message...}
function error() {
    local LEVEL=$1; shift
    if [ $VERBOSE -gt -1 ]; then
        log "[$SCRIPT_NAME] Error: ${@}"
    fi
    exit $LEVEL
}

# Write out a command and run it
# vexec {minVerbosity} {prefixMessage} {command...}
function vexec() {
    local LEVEL=$1; shift
    local MSG="$1"; shift
    if [ $VERBOSE -ge $LEVEL ]; then
        echo -n "$MSG: "
        local CMD=( )
        for i in "${@}"; do
            # Replace argument spaces with ''; if different, quote the string
            if [ "$i" != "${i/ /}" ]; then
                CMD=( ${CMD[@]} "'${i}'" )
            else
                CMD=( ${CMD[@]} $i )
            fi
        done
        echo "${CMD[@]}"
    fi
    ${@}
}

# Loop over arguments; we'll be shifting the list as we go,
# so we keep going until $1 is empty
while [ -n "$1" ]; do
    # Capture and shift the argument.
    ARG="$1"
    shift
    case "$ARG" in
        # User requested help; sometimes they do this at the end of a command
        # while they're building it.  By capturing and exiting, we avoid doing
        # work before it intended.
        -h|-\?|-help|--help)
            usage 0
            ;;
        # Make the script more verbose
        -v|--verbose)
            VERBOSE=$((VERBOSE + 1))
            ;;
        # Make the script quieter
        -q|--quiet)
            VERBOSE=$((VERBOSE - 1))
            ;;
        # All arguments that follow are non-flags
        # This should be in all of your scripts, to more easily support filenames
        # that start with hyphens.  Break will bail from the `for` loop above.
        --)
            break
            ;;
        # Something that looks like a flag, but is not; report an error and die
        -?*)
            usage 1 "Unknown option: '$ARG'" >&2
            ;;
        #
        # All other arguments are added to the ARGS array.
        *)
            ARGS=(${ARGS[@]} "$ARG")
            ;;
    esac
done
# If the above script found a '--' argument, there will still be items in $*;
# move them into ARGS
while [ -n "$1" ]; do
    ARGS=(${ARGS[@]} "$1")
    shift
done

# Main script goes here.

Далее...

vexec 1 "Building myapp.c" \
    gcc -c myapp.c -o build/myapp.o ${CFLAGS}

Примечание. Это не будет охватывать команды с каналами; вам нужно bash -c такие вещи или разбить их на промежуточные переменные или файлы.

Ответ 5

Две полезные опции оболочки, которые можно добавить в командную строку bash или через команду set в script или интерактивном сеансе:

  • -v Печатать строки ввода оболочки, когда они читаются.
  • -x. После расширения каждой простой команды команда for, команда case, команда select или команда арифметики for, отображение расширенное значение PS4, за которым следует команда и ее расширенная аргументы или список связанных слов.

Ответ 6

Для дополнительных временных меток и информации ввода-вывода рассмотрите команду annotate-output в пакете Debian devscripts:

annotate-output echo hello

Вывод:

13:19:08 I: Started echo hello
13:19:08 O: hello
13:19:08 I: Finished with exitcode 0

Теперь найдите файл, который не существует, и обратите внимание на E: для вывода STDERR:

annotate-output ls nosuchfile

Вывод:

13:19:48 I: Started ls nosuchfile
13:19:48 E: ls: cannot access 'nosuchfile': No such file or directory
13:19:48 I: Finished with exitcode 2

Ответ 7

Создайте исполняемый (+x) базовый скрипт с именем "echo_and_run" с помощью нижеприведенного простого сценария оболочки!

#!/bin/bash
echo "$*"
[email protected]

$./echo_and_run "echo Hello, World"

echo Hello, World
Hello, World

Или просто используйте одну функцию лайнера bash.

echo_and_run() { echo "\$ $*" ; "[email protected]" ; }

Однако подход cnicutar к set -x надежен и настоятельно рекомендуется.