Функция Bash не выполняет команду ввода

#bash #bash-function

#bash #bash-функция

Вопрос:

В файле bash s.sh у меня есть функция-исполнитель, которой я передаю команды для выполнения. Всякий раз, когда какая-либо команда работает не так, как ожидалось, эта функция выводит команду.

 Executor()
{
    if ! $*
    then
        echo "$*"
        exit 2
    fi
}
  

Теперь я вызываю эту функцию —

Executor clangPath="Hello" make (Это используется для установки значения переменной clangPath как «Hello» в makefile)

Это вызвало ошибку —

 ./s.sh: line 5: clangPath=Hello: command not found
[./s.sh] Error: clangPath=Hello make
  

Однако выполнение той же команды, что и эта, работает нормально

 if ! clangPath="Hello" make
then
    echo "HelloWorld!"
fi
  

Посмотрев на ошибку, я подумал, что может быть ошибка со строковыми кавычками, поэтому я попытался

exitIfFail clangPath='"Hello"' make

Даже это привело к ошибке —

 ./s.sh: line 5: clangPath="Hello": command not found
[./s.sh] Error: clangPath="Hello" make
  

В чем может быть причина ошибки?

Комментарии:

1. Вы могли бы попробовать, если! /usr/bin/ksh $* … в зависимости от того, где и какую оболочку вы используете? У меня нет возможности протестировать здесь.

2. См. Faq по Bash 050 .

3. Фу, $* … Я думаю, вы неправильно "$@" написали.

Ответ №1:

Если целью функции является выполнение некоторого выражения Bash, затем выведите сообщение об ошибке, если выражение не удалось (возвращено ненулевое состояние), то есть способ реализовать это через eval :

 #!/bin/bash -

function Executor()
{
  eval "$@"

  if [ $? -ne 0 ]
  then
    echo >amp;2 "Failed to execute command: $@"
    exit 2
  fi
}
  

$? Переменная содержит статус завершения ранее выполненной команды. Итак, мы проверяем, не равно ли оно нулю.

Также обратите внимание, как мы перенаправляем сообщение об ошибке в стандартный дескриптор ошибки.

Использование:

 Executor ls -lh /tmp/unknown-something
ls: cannot access /tmp/unknown-something: No such file or directory
Failed to execute command: ls -lh /tmp/unknown-something


Executor ls -lh /tmp
# some file listing here...
  

$@ Переменная здесь более уместна, поскольку eval сама интерпретирует вещи. См . $* и $@ .

Комментарии:

1. Что с test $? анти-шаблоном ? Простой if ! eval "$@" был бы короче, понятнее и более соответствует вопросу, и eval "$@" amp;amp; return он еще проще.

2. @TobySpeight, это вопрос предпочтений. Некоторые могут подумать об этом как об антишаблоне. Но стиль, используемый в ответе, выглядит для меня довольно понятным.