Я могу “экспортировать” функции в ударе?

Вы могли получить эту рекурсивную функцию:

#!/bin/bash
ininterval () {
    delay=$1
    shift
    $*
    sleep $delay
    ininterval $delay $*
}

или добавьте:

ininterval $*

и назовите сценарий.

87
17.10.2011, 21:44
8 ответов

В Bash можно экспортировать функциональные определения для подокружения с

export -f function_name

Например, можно попробовать этот простой пример:

./script1:

    #!/bin/bash

    myfun() {
        echo "Hello!"
    }

    export -f myfun
    ./script2

./script2:

    #!/bin/bash

    myfun

Затем, если Вы звоните ./script1 Вы будете видеть вывод Привет!.

132
27.01.2020, 19:30

Вы не можете экспортировать функции, не в способе, которым Вы описываете. Оболочка только загрузится ~/.bashrc файл на запуске интерактивной оболочки (ищут "Вызов" в странице справочника удара).

То, что можно сделать, создают "библиотеку", которая загружается, когда Вы запускаете программу:

source "$HOME/lib/somefile"

И поместите свои неинтерактивные функции и настройки туда.

5
27.01.2020, 19:30
  • 1
    Таким образом, я должен или запустить подоболочку с параметра "входа в систему" (для парсинга ~/.profile) или источник тот файл. –  Nils 17.10.2011, 22:11
  • 2
    Смотря немного более тесно, на неинтерактивных оболочках, Вы могли установить BASH_ENV переменная среды к some_file Вы уже имеете, и это назвали бы. Было бы достаточно легко узнать это: echo echo foobar > /tmp/foobar; BASH_ENV=/tmp/foobar $SHELL -c : –  Arcege 17.10.2011, 22:20

Функции не экспортируются в подпроцессы. Поэтому существуют файлы, названные .kshrc или .bashrc: определить функции что shoiuld быть доступным в подоболочках также.

При запущении скрипта обычно не получаются.*shrc сценарии. Необходимо было бы кодировать это явно, как в . ~/.kshrc.

1
27.01.2020, 19:30
  • 1
    Таким образом, ~root/.bashrc мог быть опцией в моем случае, так как скрипты запущены как корень. Спасибо за ту подсказку. –  Nils 17.10.2011, 22:06
  • 2
    шарика при использовании.*shrc файлов, была бы уверена, что они не вызывают интерактивное поведение (как глупый псевдоним rm=rm -i) –  ktf 18.10.2011, 11:50

Ну, я плохо знаком с Linux, но можно попробовать это. В некотором файле давайте назовем его, 'tmp/general' Вы создают Вашу функцию:

func1(){
   echo "func from general"
}

В Вашем сценарии оболочки добавьте:

. /tmp/general

и выполненный:

func1

Вы войдете в экран: func from general.

1
27.01.2020, 19:30

"Экспорт" функции с помощью экспорта -f создает переменную окружения с телом функции. Рассмотрим этот пример:

$ fn(){ echo \'\"\ \ \$; }
$ export -f fn
$ sh -c printenv\ fn
() {  echo \'\"\ \ \$
}

Это означает, что только оболочка (только Бэш?) сможет принять функцию. Вы также можете установить функцию самостоятельно, так как Бэш рассматривает envvars только начиная с () { как функцию:

$ fn2='() { echo Hi;}' sh -c fn2
Hi
$ fn3='() {' sh -c :
sh: fn3: line 1: syntax error: unexpected end of file
sh: error importing function definition for `fn3'

Если вам нужно "экспортировать" эту переменную по SSH, то вам действительно нужна функция в виде строки. Это можно сделать с помощью опции печати (-p) для функций (-f) встроенного объявления -:

$ declare -pf fn
fn () 
{ 
    echo \'\"\ \ \$
}

Это очень полезно, если у вас есть более сложный код, который нужно выполнить по SSH. Рассмотрим следующий вымышленный сценарий:

#!/bin/bash
remote_main() {
   local dest="$HOME/destination"

   tar xzv -C "$dest"
   chgrp -R www-data "$dest"
   # Ensure that newly written files have the 'www-data' group too
   find "$dest" -type d -exec chmod g+s {} \;
}
tar cz files/ | ssh user@host "$(declare -pf remote_main); remote_main"
17
27.01.2020, 19:30

Основываясь на ответе @ Lekensteyn ...

Если вы используете declare -pf , он выведет все ранее определенные функции в текущей оболочке в STDOUT.

На этом этапе вы можете перенаправить STDOUT куда хотите и, по сути, заполнить ранее определенные функции, где захотите.

Следующий ответ поместит их в переменную. Затем мы повторяем эту переменную плюс вызов функции, которую хотим запустить в новую оболочку, созданную как новый пользователь. Мы делаем это, используя sudo с переключателем -u (он же пользователь ) и просто запускаем Bash (который получит передаваемый STDOUT в качестве входных данных для запуска ).

Поскольку мы знаем, что мы переходим от оболочки Bash к оболочке Bash, мы знаем, что Bash будет правильно интерпретировать функции, определенные предыдущими оболочками. Синтаксис должен быть в порядке, пока мы перемещаемся между одной оболочкой Bash той же версии и новой оболочкой Bash той же версии.

YMMV, если вы перемещаетесь между разными оболочками или между системами, в которых могут быть разные версии Bash.

#!/bin/bash
foo() {
  echo "hello from `whoami`"
}

FUNCTIONS=`declare -pf`; echo "$FUNCTIONS ; foo" | sudo -u otheruser bash
# $./test.sh
# hello from otheruser
8
27.01.2020, 19:30
declare -x -f NAME

Больше информации

-f        restrict action or display to function names and definitions
-x        to make NAMEs export
1
27.01.2020, 19:30

EVAL "$ (DECLARE -F | SED -E 'S /F / -FX /')" будет экспортироваться все функции .

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

Пример:

eval "$(declare -F | sed -e 's/-f /-fx /')"
export SOME IMPORTANT VARIABLES AND PASSWORDS
bash -i
3
27.01.2020, 19:30

Теги

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