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

Я могу определить функцию как:

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. Чтобы добавить к путанице, есть эта команда ., которая, кажется, не имеет ничего общего с "." это означает «текущий каталог».

4
задан 4 June 2012 в 03:32

3 ответа

Определение функции влияет только на текущий экземпляр bash. Когда вы пишете

echo "myfunction ." | bash

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

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

my_snippet='myfunction .'
eval "$my_snippet"

Если вы определяете функции в .bashrc, они доступны только в интерактивных оболочках, а не в скриптах.

Команда . (почти) эквивалентна source и не имеет ничего общего с ., означающим текущий каталог.

0
ответ дан 4 June 2012 в 03:32

Вместо использования eval, вы можете export свою функцию, чтобы она наследовалась подоболочками:

myfunction () { ls -R "$1" ; }
export -f myfunction

А затем

echo "myfunction ." | bash

просто работает.

echo "myfunction ." | sh, вероятно, не остановится, если только ваш / bin / sh не является символической ссылкой на bash.

0
ответ дан 4 June 2012 в 03:32

bash и sh ожидайте, что их аргументом будет исполняемый файл, не строка.

Можно выполнить содержание строки с

eval "myfunction ."

Когда Вы запустите программу через оболочку, она будет обычно вызывать новый экземпляр bash (или sh, csh, zsh, и т.д. как соответствующие), наследуйте настройки всей исходной оболочки и выполните себя в новой оболочке. Это позволяет Вам временно устанавливать переменные или изменять настройки, не вмешиваясь в Вашу среду.

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

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

1
ответ дан 4 June 2012 в 03:32

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

Похожие вопросы: