Использование функции, определенной в родительском скрипте

Я написал следующий скрипт в test.sh:

#!/bin/sh compare() { if [ $1 != root ]; then echo "Fail" >> CAT1.txt fi } awk -F: '$4 == 0' /etc/passwd | cut -d: f1 | xargs -n1 -i bash -c 'compare "$@"' _ 

при выполнении этих скриптов, получите следующую ошибку:

 _: compare: command not found 

3 Solutions collect form web for “Использование функции, определенной в родительском скрипте”

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

(Функции доступны в подоболочках, т. Е. Когда выполняется копия рабочей оболочки для запуска чего-либо в скобках (…) или для подстановки $(…) и т. Д. Но они недоступны в отдельных программах, например, когда вы запускаете sh -c … )

Определите функцию в скрипте, который ее использует:

 #!/bin/sh awk -F: '$4 == 0' /etc/passwd | cut -d: f1 | xargs -n1 -i bash -c ' compare() { if [ $1 != root ]; then echo "Fail" >> CAT1.txt fi } compare "$@"' _ 

(Я предполагаю, что это пример игрушки, все это можно сделать в одном простом awk-скрипте.)

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

 #!/bin/bash compare() { if [ $1 != root ]; then echo "Fail" >> CAT1.txt fi } export -f compare awk -F: '$4 == 0' /etc/passwd | cut -d: f1 | xargs -n1 -i bash -c 'compare "$@"' _ 
  1. почему бы не использовать …?

     awk -F: '$4==0 && $1 != root ' /etc/passwd > CAT1.txt 

    1.1 изменить, чтобы получить сбой

     awk -F: '$4==0 && $1 != root {print "Fail" ; } /etc/passwd > CAT1.txt 

    получить отказ И имя пользователя

     awk -F: '$4==0 && $1 != root {printf "Fail %s\n",$1 ; } /etc/passwd > CAT1.txt 
  2. определение функции теряется при разветвлении нового bash. Ae @mueh сказал вам, вам нужно export -f compare .

Вы должны сделать это с помощью какой-либо логики разветвления. Установите некоторый маркер в среде вашего скрипта, который определенно докажет дочерним экземплярам вашего скрипта, что они должны делать одно, а родитель – другой. Таким образом, вы можете сделать сценарий безопасным рекурсивным.

 #!/bin/sh case $Z:$P in ("$0:${1:-!$P}") [ root = "$2" ] || ! echo Fail ;;(*) set -a; Z=$0 P=$$ </etc/passwd \ awk -F: '$4 == 0'| cut -d: -f1 | xargs -n1 "$0" "$$" esac >>CAT1.txt 

Или, может быть, используйте ваши fds, чтобы сделать чек. Если вы запускаете скрипт в первую очередь с терминала, тогда …

 #!/bin/sh [ -t 0 ] && { awk '$4 == 0' | cut -d: -f1 | xargs -n1 "$0" exit } </etc/passwd >>CAT1.txt [ root = "$1" ] || ! echo Fail 

Но лучший способ – это, фактически, изменить $0 ребенка:

 #!/bin/sh [ . = "$0" ] && { [ root = "$1" ] || ! echo Fail } z=$(head -n5 <"$0") </etc/passwd \ awk '$4 == 0' | cut -d: -f1 | >>CAT1.txt \ xargs -n1 \ sh -c "$z" . 
  • Как создать бесконечный поток строк в bash
  • Пропустить входной файл через трубу в качестве аргумента?
  • Как объединить входы xarg с большим количеством аргументов?
  • команда solaris + xargs для солярия
  • Zgrep останавливается после первого совпадения, когда аргументы передаются из xargs
  • найти . . * -тип f -print0 | xargs -0 sudo chmod 664; не работает
  • xargs, записи и стандартный ввод
  • Удалите все повторяющиеся слова из строки, используя сценарий оболочки
  • рекурсивно chmod
  • Есть ли команда Unix для цитирования строк ввода?
  • Можете ли вы подключиться к функции .bash_profile?
  • Linux и Unix - лучшая ОС в мире.