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

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

то есть, если выполняется сценарий оболочки, например

echo "Hello, World"

Я хотел бы следующий вывод

echo "Hello, World"
Hello, World

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

$ echo_and_run echo "Hello, World"
echo "Hello, World"
Hello, World

7 ответов


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

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

cnicutar@shell:~/dir$ set -x
cnicutar@shell:~/dir$ ls
+ ls --color=auto
a  b  c  d  e  f

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

echo_and_run() { echo "$@" ; "$@" ; }

я использую что-то вроде этого:

echo_and_run() { echo "$ $@" ; "$@" ; }

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

как другие упоминали, оно теряет цитату Маркс:

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

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


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

function echo_and_run {
  echo "$" "$@"
  eval $(printf '%q ' "$@") < /dev/tty
}

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

#!/bin/sh

# Control verbosity
VERBOSE=0

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

ARGS=()

# Usage function: tells the user what's up, then exits.  ALWAYS implement this.
# Optionally, prints an error message
# usage [{errorLevel} {message...}
function usage() {
    local RET=0
    if [ $# -gt 0 ]; then
        RET=; 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=; 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=; shift
    local MSG=""; shift
    if [ $VERBOSE -ge $LEVEL ]; then
        echo -n "$MSG: "
        local CMD=( )
        for i in "${@}"; do
            # Replace argument's 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  is empty
while [ -n "" ]; do
    # Capture and shift the argument.
    ARG=""
    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's 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 "" ]; do
    ARGS=(${ARGS[@]} "")
    shift
done

# Main script goes here.

позже...

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

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


два полезных параметра оболочки, которые могут быть добавлены в bash командной строки или через set команда в скрипте или интерактивном сеансе:

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

для дополнительных временных меток и информации ввода / вывода, рассмотрим С Debian ' s 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

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

#!/bin/bash
echo ""

$ ./echo_and_run "Эхо Привет, Мир"

echo Hello, World
Hello, World
, cnicutar это approch к set -x надежно и сильно порекомендовано.