シェル変数名にハイフンまたはダッシュ(-)を含めることができますか?


38

-シェルの変数で使用することはできません。そのような名前付き変数に依存するスクリプトが1つあるため、それを使用する方法はありますか?

$export a-b=c
-bash: export: `a-b=c': not a valid identifier

$export a_b=c

最初に指定されたエラーをスローし、2番目は正常に動作します。



シェルは通常、そのような変数名を許可しません。カスタムCプログラムがコマンドの環境に変数をロードしている場合でも、シェルをバイパスする必要があります。この誤機能を修正することはできませんか?
フォンブランド

回答:


47

-変数名に使用できるBourneスタイルのシェルに出会ったことはありません。ASCII文字(どちらの場合も)_と数字のみがサポートされており、最初の文字は数字であってはなりません。

シェルの制限に一致しない環境変数を必要とするプログラムがある場合は、そのプログラムで起動しenvます。

env 'strange-name=some value' myprogram

一部のシェル(モダンダッシュ、mksh、zshなど)は、名前が好ましくない変数を環境から削除することに注意してください。(Shellshockにより、環境変数の名前に注意が向けられるようになったため、時間の経過とともに制限が厳しくなり、より寛容ではなくなります。)したがって、名前に特殊文字を含む変数をプログラムに渡す必要がある場合は、直接渡します。間にシェルenv 'strange-name=some value' sh -c'…; myprogram'がない場合(機能する場合と機能しない場合があります)。


動作しなくなりました。
ジェシーグリック

4
@JesseGlickはい、できます。(あなたは「動作しない」が定義されていればコメントが有用であろう:どのようなデータを代わりに所望の効果の効果は何であり、あなたはどの言った場合の実装??envあなたはどのようなオペレーティングシステム上で使用されます。)
ジル「SO-停止ビーイング邪悪 '

ごめんなさい。すべての更新とUbuntuのYakkety、envからcoreutilsshからdashenv 'with-dashes=value' bash -c 'env | fgrep dashes'動作しますが、env 'with-dashes=value' sh -c 'env | fgrep dashes'何も出力しません。つまり、envそれ自体は問題ありませんが、Dashはこれらの変数を特にブロックしているようです。したがって、問題のプログラムが典型的な#!/bin/shヘッダーを持つシェルラッパーを介して起動された場合、そのような変数を渡す明確な方法はありません。回避策の例
ジェシーグリック

@JesseGlickそれは変数を削除するダッシュです。あなたは使用する必要がありますenv間で殻なしに、この変数名を必要とするプログラムの呼び出しサイトに近いです。ダッシュは、名前が気に入らない変数を削除するだけではありません。
ジル 'SO-悪であるのをやめる'

1
@JesseGlickそれの本当の仕事に使用したことをいくつかのものは、もはや仕事かもしれない、けれども:以来、2014年シェルショック脆弱性、人々は変数名について、より保守的になってきている、とダッシュは事実で行った変更私は(ない、しかし2014年シェルショック脆弱性の結果として、この答えを書いたので、しかし、同じ行に沿ってバグを回避するため)。回答にメモを追加しました。
ジル 'SO-悪であるのをやめる'

15

それはBashでは不可能です。

のマニュアルページの定義セクションからbash

名前英数字とアンダースコアのみで構成され、アルファベット文字またはアンダースコアで始まる単語。識別子とも呼ばれます。

のマニュアルページのパラメータセクションからbash

パラメータは、値を保存するエンティティです。名前、番号、または下の「特殊パラメーター」にリストされている特殊文字のいずれかです。変数は、名前で示されるパラメーターです。


2
マニュアルページの有用性をもう一度実証するために+1
ktf

2
古い記事は知っていますが、新人のマニュアルページは非常にわかりにくいことがあります。もっと良い説明/例を探し出す必要があるときがまだあります。彼らはそれが彼らに決して起こらなかったと言ったら誰もが嘘をついているでしょう。
TCZ8 14

1
@ TCZ8マニュアルページが「不可解だ」と思ったと言ったのは、エラーメッセージを読まず、読みたいものを読み飛ばすだけの人です。
マイルルーティング

13

間接参照を使用して、ハイフネーションされた変数にアクセスできます。

$ env 'my-hyphenated-variable=hello' /bin/bash
$ name='my-hyphenated-variable'
$ echo ${!name}
hello

1
このコメントを読むまで、この機能について聞いたことがありませんでした。
DrStrangepork

7
この動作は、bashの新しいバージョンでは無効になっています。状況の徹底的な分析については、stackoverflow.com / questions / 36989263 /…を参照してください。
ニコラスDudebout

6

スクリプトが変数名にハイフンを含めることに依存している場合、それはプログラミングエラーです。変数名にハイフンを含めるために定期的に使用するツールのために便利な場合は、より多くの異なるツールを学習する必要があります。

trを使用してハイフンをアンダースコアに変換しようとしましたか?

hyphenated_name="a-b"
unhyphenated_name=$(echo $hyphenated_name | tr '-' '_')
declare -x $unhyphenated_name="some value"

Bashでは、関数名に「-」を使用できます。私はこれをいつもしています。例えば:

function foo-bar() {
   echo "$@"
}

2

ダッシュ(-)文字はブレーク文字であり、変数名の一部として許可されていません。引用符で囲まれた変数を使用してこれをハックする方法はありますが、その解析には本当に問題があります。また、bashの変数名のコンテキストで特別な意味を持つ他の文字、特に中括弧、括弧、演算子文字、引用符もあります。(例{}()=+-&'"など)

実際に、スクリプトを構築するための別のパラダイムを見つける必要があることをお勧めします。「変数変数名」について、他の言語からのアイデアに二日酔いを抱くかもしれません。通常、これはシェルスクリプトではお勧めできません。

これを編集するか、コンテキストの詳細と何を達成しようとしているのかについて新しい質問をする場合、スクリプトを作成するための良い方法を提案できるかもしれません。


2

Bashマニュアルでは、「名前」を次のように定義しています。

文字、数字、アンダースコアのみで構成され、文字またはアンダースコアで始まる「単語」。「名前」はシェル変数および関数名として使用されます。「識別子」とも呼ばれます。

したがって、名前にハイフンを使用することはできません。


0

ほとんどのシェルは、変数名に対してaz、AZ、0-9、および_のみをサポートしています。このページの 2番目の項目をお読みください


0

envおよびsedで遊ぶことができます。

例として、この変数「ELASTICSEARCH_CLUSTER-NODES」を読み取る必要がありました。
envコマンドの出力は次のとおりです。

~ $ env
ELASTICSEARCH_CLUSTER-NODES=elasticsearch:9200
JAVA_ALPINE_VERSION=8.212.04-r0
HOSTNAME=17eb9e7fec4c
...

変数を抽出するには:

ESHOST=`env | sed -n 's/ELASTICSEARCH_CLUSTER-NODES=\(.*\)/\1/p'`

-1

bash変数には文字、数字、アンダースコアのみが許可されていると思います。これは多くのプログラミング言語の場合です(javascriptは例外です)。

スクリプトをこれらのタイプの変数名に依存させないことをお勧めします。

実際、変数名を他の名前に置き換えることができ、違いが生じないような方法でプログラミングする必要があります。一般に、変数名には変数に含まれるものを記述する必要があります。これにより、デバッグがはるかに簡単になります。そうでない場合は、コードを理解しようとしている次の開発者のために。


-1

このenvコマンドを使用して、ハイフン「-」で環境変数を設定および設定解除できます。

設定するには、あなたのコマンドを実行するためにENV使用する必要がありますenv command。この方法で変数を渡します。

env a-b=c command

動作をご覧ください:

env a-b=c env

またはそれを明確にする:

env a-b=c env|grep 'a-b'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.