親スクリプトで定義された関数の使用

親スクリプトで定義された関数の使用

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

答え1

関数は、その関数が定義されているシェルの内側にあります。別のプログラムを実行すると、そのプログラムがシェルであってもその機能を見ることはできません。

(関数はサブシェルからアクセスできます。つまり、実行中のシェルのコピーを作成して角かっこ内のエントリを実行したり、コマンドの置き換えなど(…)$(…)ためにアクセスしたりできます。ただし、別のプログラムではアクセスできません(例:とき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固有の機能なので、親スクリプトはshではなくbashを実行する必要があります。

#!/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 "$@"' _

答え2

  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

答え3

これを行うには、ある種の分岐ロジックを使用する必要があります。スクリプトの子インスタンスが1つのタスクを実行し、親インスタンスが別のタスクを実行する必要があることを確実に示すフラグをスクリプト環境に設定します。これにより、スクリプトを安全に再帰的に作成できます。

#!/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" . 

関連情報