インポートされたpasswdファイルに基づいてユーザーディレクトリを作成しようとしていますが、データをにロードしようとしています。連想配列:array [username] = directory。フィールドを個別の配列にロードすることはできますが、各フィールドがすべてのディレクトリに関連付けられるため、関連付けを正しく行うことができません。
USERLIST=$(cat /usrmkr/in.out | awk -F ":" "{print $1}") DIRLIST=$(cat /usrmkr/in.out | awk -F ":" "{print $6}") declare -A USERARRAY func_StoreData() { USERARRAY[$1]="$2" return $? } for ((u=0;u<${USERLIST[@]};u++)); do func_StoreData ${USERLIST[$u]} ${DIRLIST[$u]} done for i in ${!USERARRAY[@]}; do echo "making directory for $i in ${USERARRAY[$i]}" #Do stuff done
コメント
- 既存の回答のいずれかで問題が解決した場合は、次の方法で受け入れることを検討してください。チェックマーク。ありがとうございます!
回答
コロンで分割するように読み取りを指示して、bashですべてを直接読み取ることができます。 :
declare -A userarray while IFS=: read -r username password uid gid gecos home shell; do userarray[$username]=$home done < /usrmkr/in.out
回答
eval declare -A USERARRAY=( $(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out) )
awk
スクリプトは、[key]=val
形式で出力を生成しますbash連想配列の複数の要素を設定する場合に必要であり、キーまたは値のいずれかにスペースやタブなどがある場合は、キーと値の両方を二重引用符で囲みます(["key"]="value"
)。 。
\n
を区切り文字として使用して、awk
他のツールで出力します(ただし、awk
は、他のツールで実行したいほとんどのことを実行できます)。
コマンド置換 だけで十分です。 。ただし、IMOが原因で、( ... )
配列定義内の最初の非空白文字がない場合、bash
のバグが発生します。 ” ta [
、エラーメッセージmust use subscript when assigning associative array
を生成するだけです。
eg USERARRAYを設定する次の両方の試みは失敗します:
$ bash --version | head -1 GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu) $ declare -A USERARRAY=($(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out)) bash: USERARRAY: $(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out): must use subscript when assigning associative array $ UA=$(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out) $ declare -A USERARRAY=( $UA ) bash: USERARRAY: $UA: must use subscript when assigning associative array
解決策は回答の上部にあるコード例のように、ハッシュ配列を宣言するときにeval
を使用します。または、
eval declare -A USERARRY=( $UA )
コメント
- 1。これは
eval
を使用します-もちろん、'にはコマンドインジェクションのリスクがあります。 'この場合、問題はないと思います'ただし、私の答えはOP
固有の&おそらく精査済み/正常な入力ファイル。 2. " 拡張を引用するのを忘れた "-え?何? '引用符の問題は見当たりません。awkコードは配列のキーと値の両方を明示的に引用します。 3.ところで、ほぼ2年後、bash v4.4.19(1)-リリースまだでは、cmd-substまたはさらには直接使用できません'ハッシュ宣言の変数:declare -A array=( $(...) )
は同じエラーで失敗するため、evalが引き続き必要です
/etc/passwd
データ。つまり、言い換えると、⚠通常の/etc/passwd
データでは問題ないはずですが、コマンドインジェクションの脆弱性を構成するため、このアプローチを任意のデータに使用しないでください。具体的には、データに'、`
、"
、バックスラッシュ、 $
、*
、?
、[
、スペースタブまたはNUL文字。$x
$x
が[123]=qwe
のようなものだったとき(bashが連想配列をサポートする前でした)。'の真のbashは、連想配列をa=("$x")
($x
は、a=([$k]=$v)
構文に加えて、[...]=
)で始まる必要がありますが、その場合、指定する方法を定義する必要があります。 ]文字を含むキー。いずれにせよ、私はそれをバグとは呼びませんが、設計上の決定(ここではbashが構文をコピーしたkshによって行われました)。