Я могу определить функцию как:
myfunction () { ls -R "$1" ; }
А потом
myfunction .
просто работает.
Но если я сделаю
echo "myfunction ." | sh
echo "myfunction ." | bash
сообщения будут:
sh: myfunction: not found
bash: line 1: myfunction: command not found
Почему? И как я могу вызвать функцию, которая приходит из строки, если не передать ее в sh или bash?
Я знаю, что есть эта команда source
, но я не совсем понимаю, когда мне следует использовать source
и когда sh
или bash
. Кроме того, я не могу пройти через source
. Чтобы добавить к путанице, есть эта команда .
, которая, кажется, не имеет ничего общего с "." это означает «текущий каталог».
Определение функции влияет только на текущий экземпляр bash. Когда вы пишете
echo "myfunction ." | bash
, вы запускаете другой экземпляр bash. Вам нужно будет определить функцию в этом другом экземпляре.
Если у вас есть строка, содержащая имя функции и аргументы (если необходимо, в кавычках) или, в более общем случае, любая строка, содержащая некоторый исходный код оболочки, который вы хотите выполнить, используйте встроенную функцию eval
.
my_snippet='myfunction .'
eval "$my_snippet"
Если вы определяете функции в .bashrc
, они доступны только в интерактивных оболочках, а не в скриптах.
Команда .
(почти) эквивалентна source
и не имеет ничего общего с .
, означающим текущий каталог.
Вместо использования eval
, вы можете export
свою функцию, чтобы она наследовалась подоболочками:
myfunction () { ls -R "$1" ; }
export -f myfunction
А затем
echo "myfunction ." | bash
просто работает.
echo "myfunction ." | sh
, вероятно, не остановится, если только ваш / bin / sh не является символической ссылкой на bash.
bash
и sh
ожидайте, что их аргументом будет исполняемый файл, не строка.
Можно выполнить содержание строки с
eval "myfunction ."
Когда Вы запустите программу через оболочку, она будет обычно вызывать новый экземпляр bash
(или sh
, csh
, zsh
, и т.д. как соответствующие), наследуйте настройки всей исходной оболочки и выполните себя в новой оболочке. Это позволяет Вам временно устанавливать переменные или изменять настройки, не вмешиваясь в Вашу среду.
source
луг команда заставит его выполнить его Ваша текущая оболочка, таким образом, любые изменения это делает к среде, сохранится, когда команда выйдет. .
синоним для source
.
При большинстве обстоятельств сценарий укажет то, что окружает его, предназначен для выполнения в (с #!/bin/bash
в его первой строке, например), и это не необходимо, чтобы Вы назвали удар явно.