source some_file
some_file:
doit ()
{
echo doit $1
}
export TEST=true
Если я использую исходный код some_file, функция «doit» и переменная TEST доступны в командной строке. Но запускаем этот скрипт:
script.sh:
#/bin/sh
echo $TEST
doit test2
Вернет значение TEST, но сгенерирует ошибку о неизвестной функции "doit".
Могу ли я тоже "экспортировать" функцию, или мне нужно найти файл some_file в script.sh, чтобы использовать эту функцию там?
#!/bin/sh
к#!/bin/bash
и послеdoit() {...}
того, как толькоexport -f doit
#!/bin/sh
тоже используете , но это хорошая практика, чтобы#!/bin/bash
избежать проблем, когда оболочкой по умолчанию не является bash.Ответы:
В Bash вы можете экспортировать определения функций в суб-оболочку с помощью
Например, вы можете попробовать этот простой пример:
./script1
:./script2
:Тогда, если вы позвоните,
./script1
вы увидите вывод Hello! ,источник
«Экспорт» функции с помощью
export -f
создает переменную окружения с телом функции. Рассмотрим этот пример:Это означает, что только оболочка (только Bash?) Сможет принять функцию. Вы также можете установить функцию самостоятельно, поскольку Bash рассматривает только envvars, начинающийся с
() {
функции:Если вам нужно «экспортировать» эту переменную через SSH, то вам действительно нужна функция в виде строки. Это можно сделать с помощью опции print (
-p
) для функций (-f
)declare
встроенного:Это очень полезно, если у вас есть более сложный код, который необходимо выполнить через SSH. Рассмотрим следующий вымышленный сценарий:
источник
fn2='() { echo Hi;}' sh -c fn2
не работал для меня. Наsh
Arch Linux с Bash v5.0.7 я получилsh: fn2: command not found
. На Ubuntu сsh
Dash v0.2.3 я получилsh: 1: fn2: not found
. Какуюsh
оболочку вы использовали?f(){ echo a;}; export -f f; echo "$f"; sh -c 'printenv f; echo "$f"'
ничего не печатает для меня, так что явноf
не экспортируется в виде простой строки. Я протестировал обе комбинации, упомянутые выше.sh
выполнять эту строку как функцию? В вашем примереfn2='() { echo Hi;}' sh -c fn2
команда,fn2
заданнаяsh
буквально, является строкой"fn2"
.sh
должен искать такую команду в своем PATH, но не должен искать, есть ли переменная$fn2
, раскрывать эту переменную и выполнять ее значение как функцию - для меня это звучит как серьезная проблема безопасности. редактировать: я думаю, что это все! Было ли ваше показанное поведение ошибкой в безопасности, известной как ShellShock / Bashdoor ?fn(){ echo foo; }; export -f fn; env | grep foo
выходыBASH_FUNC_fn%%=() { echo foo
Опираясь на ответ @ Лекенштейна ...
Если вы используете
declare -pf
его, выведите все ранее определенные функции в текущей оболочке в STDOUT.В этот момент вы можете перенаправить STDOUT туда, куда вам нужно, и, по сути, заполнить ранее определенные функции, куда вы хотите.
Следующий ответ поместит их в переменную. Затем мы повторяем эту переменную плюс вызов функции, которую мы хотим запустить в новую оболочку, которая создается как новый пользователь. Мы делаем это, используя
sudo
с-u
(ака.user
) Переключатель и просто запустив Bash (который получит водопроводную STDOUT в качестве входных данных для запуска).Поскольку мы знаем, что мы идем от оболочки Bash к оболочке Bash, мы знаем, что Bash будет правильно интерпретировать функции, определенные предыдущими оболочками. Синтаксис должен быть в порядке, пока мы перемещаемся между одной оболочкой Bash той же версии и новой оболочкой Bash той же версии.
YMMV, если вы перемещаетесь между разными оболочками или между системами, которые могут иметь разные версии Bash.
источник
Вы не можете экспортировать функции, не так, как вы описываете. Оболочка будет загружать
~/.bashrc
файл только при запуске интерактивной оболочки (поиск «Invocation» на странице руководства bash ).Что вы можете сделать, это создать «библиотеку», которая загружается при запуске программы:
И разместите там свои неинтерактивные функции и настройки.
источник
BASH_ENV
переменную окружения, которая уsome_file
вас уже есть, и она будет вызвана. Было бы достаточно легко это выяснить:echo echo foobar > /tmp/foobar; BASH_ENV=/tmp/foobar $SHELL -c :
eval "$(declare -F | sed -e 's/-f /-fx /')"
будет экспортировать все функции.Я делаю это много до запуска интерактивной оболочки в скрипте, чтобы позволить мне отлаживать и работать в контексте скрипта, используя его функции и переменные.
Пример:
источник
Функции не экспортируются в подпроцессы. Вот почему существуют файлы с именами .kshrc или .bashrc: для определения функций, которые также будут доступны в подоболочках.
При запуске сценария сценарии. * Shrc обычно не создаются. Вы должны были бы кодировать это явно, как в
. ~/.kshrc
.источник
rm=rm -i
)Ну, я новичок в Linux, но вы можете попробовать это. В каком-то файле, назовем его «tmp / general», вы создаете свою функцию:
В вашем сценарии оболочки добавьте:
и запустить:
Вы получите на экране:
func from general
.источник
Больше информации
источник