ローカル変数の割り当てには引用符が必要ですか?

ローカル変数の割り当てには引用符が必要ですか?

ローカルタスクの右側にある引用符を安全に省略できますか?

function foo {
    local myvar=${bar}
    stuff()
}

私は主に興味がありますが、bash他のシェルのコーナーケースに関する情報は大歓迎です。

答え1

export foo="$var"またはlocal foo="$var"(またはreadonlytypesetおよびdeclare他の変数宣言には引用符が必要です)注文する)存在する:

  • dashバージョン0.3.8-15〜0.5.10.2(参照)変化)。
  • NetBSD sh(また、Almquistシェルベース)。
  • shFreeBSD 9.2以前(参照)9.3の変更点)
  • yash
  • zsh5.1より前のバージョンにはエミュレーションが含まれていましたkshshまたは単語を区切るexport var="$(cmd)"場所zsh(ワイルドカードではありません))。

それ以外の場合、変数拡張は他のコマンドの引数と同様にトークン化および/またはファイル名の生成の影響を受けます。

次の場合は必要ありません。

  • bash
  • ksh(すべての実装)
  • FreeBSD sh9.3以降
  • ashベースのbusybox」sh(2005年から)
  • zsh
  • dash0.5.11以上。

では、inまたはエミュレーションをzsh除き、引数拡張では分割+globは行われませんが、コマンド置換では分割(globではない)が行われます。バージョン 5.1 以降、およびその他の宣言コマンドが二重に変更されました。shkshexportlocalキーワード/組み込み上記の他のシェルのコマンドと同様に、これは、sh/kshエミュレーション内であってもコマンド置換の場合でも引用が必要ないことを意味します。

一部の特殊なケースでは、これらのシェルでも引用が必要です。たとえば、次のようになります。

a="b=some value"
export "$a"

=あるいは、より一般的には、(included)の残りの部分が=引用されている場合、または一部の拡張の結果である場合(例えば、またはexport 'foo'="$var"export foo\="$var"実際export foo$((n+=1))="$var"$((...))も引用する必要があります)...)。つまり、exportno にある場合ですexport

export/localコマンド名自体が引用符で囲まれている場合(、、、、"export" a="$b"などの部分も)、AT&Tおよび最新バージョンを除いて引用符'ex'port a="$b"が必要です。\export a="$b"""export a="$b"$bkshmkshdash

export/またはその一部が一部の拡張(inまたはEvenなど)の結果である場合は、local引用符が必要ですが、最新バージョンの。cmd=export; "$cmd" a="$b"export$(:) a="$b"dryrun=; $dryrun export a="$b"dash

場合によっては、> /dev/null export a="$b"一部のpdkshデリバティブに関する見積もりが必要です。

、Except、、最新、および(Except以外のシェルの特定の拡張結果にも同じ警告が適用されます)、すべてのシェルにはcommand export a="$b"引用符が必要です。mkshksh93dashbash -o posixcommandexportdash

作成されると、どのシェルでも必要ありません。

foo=$var export foo

(この構文はBourneシェルとも互換性がありますが、最新バージョンでは/エミュレーションzshでのみ機能します。)shksh

var=value local var他のシェルは異なる動作をするため、これを使用しないでください)。

exportまた、割り当てとともに使用すると、cmdinの終了状態がexport var="$(cmd)"失われるという意味でもあります。これを行うと、export var; var=$(cmd)この問題は発生しません。

また、次の特別な場合に注意してくださいbash

$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b

私のアドバイスは常に引用することです。

答え2

私は通常、空白などの文字が存在する可能性のある変数の使用法を引用します。それ以外の場合は、次の問題が発生します。

#!/bin/bash

bar="hi bye"

function foo {
  local myvar=${bar}
  printf "%s\n" $myvar
  printf "%s\n" "$myvar"
}

foo

代入で変数を使用するには引用符が必要ないようですが、のように変数を使用するには引用符をprintf付ける必要があります。

  printf "%s\n" "$myvar"

メモ:変数によって区切り$IFS文字の内容が決まることに注意してください。

IFS    The  Internal  Field  Separator that is used for word splitting after 
       expansion and to split lines into words with the read builtin command. 
       The default value is ``<space><tab><newline>''.

はい

Bashでデバッグを有効にすると、後で何が起こっているのかを確認できます。

$ bash -x cmd.bash 
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye

上記では、変数がうまく$bar渡されていることがわかりますが、$myvar変数を使用するときは、変数をどのように使用するかを $myvar理解する必要があります。$myvar

関連情報