Bash: как использовать функцию (которая является строковым параметром) в другой функции

У меня есть эти функции в моем.bashrc:

# This function just untar a file:
untar()
{
    tar xvf $1
}

# This function execute a command with nohup (you can leave the terminal) and nice for a low priority on the cpu:
nn()
{
    nohup nice -n 15 "$@" &
}

Перед тестированием функции nn я создаю tar:

echo test > test.txt
tar cvf test.txt.tar test.txt

Теперь я хочу сделать следующее:

nn untar test.txt.tar

Но только это работает:

nn tar xvf test.txt.tar

Здесь ошибка в nohup.out:

nice: ‘untar’: No such file or directory

1 ответ

Решение

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

export -f untar
nn bash -c 'untar test.txt.tar'

Вы можете автоматизировать это, если хотите облегчить вызов:

nn() {
    if [[ $(type -t "$1") == function ]]; then
        export -f "$1"
        set -- bash -c '"$@"' bash "$@"
    fi

    nohup nice -n 15 "$@" &
}

Эта строка заслуживает объяснения:

set -- bash -c '"$@"' bash "$@"
  1. set -- изменяет аргументы текущей функции; это заменяет "$@" с новым набором значений.
  2. bash -c '"$@"' явный вызов subshell.
  3. bash "$@" аргументы для подоболочки bash является $0 (не используется). Внешние существующие аргументы "$@" передаются в новый экземпляр bash как $1, $2и т. д. Вот так мы получаем подоболочку для выполнения вызова функции.

Посмотрим, что произойдет, если вы позвоните nn untar test.txt.tar, type -t проверка видит, что untar это функция. Функция экспортируется. затем set изменения nnаргументы от untar test.txt.tar в bash -c '"$@"' bash untar test.txt.tar,

Другие вопросы по тегам