`source`コマンドの反対


9

source変数の値を読み取り/印刷するために、bashスクリプトでコマンドを使用します

more linuxmachines_mount_point.txt

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"

source  linuxmachines_mount_point.txt

echo $linuxmachine01
sdb sdc sdf sdd sde sdg

source変数を設定解除するための反対は何ですか?

予期された結果

echo $linuxmachine01

< no output >

14
それはsourceあなたの環境で変数を設定することではなく、あなたがexportするファイルのステートメントですsource。したがって、すべてが同じ変数である別のファイルの場合sourceは、の逆になります。sourcesourceunset
user4556274 '30 / 12/30

2
yael、エクスポートを使用せず、name = "val"を使用してください。エクスポートは、スクリプトからバイナリへの変数(環境)用です。
ctrl-d


2
不可能だよ。あなたが探している概念は、リバーシブルコンピューティングと呼ばれています。プログラミング言語は、元に戻せるようにするために、いくつかの厳しい制限を設けて特別に設計する必要があります。Bashはこれらのプログラミング言語の1つではありません。
イェルクWミッターク

1
@yael、それは真実ではありません(そして、ctrl-dに指示するテストを実行したことはありません); あなたは絶対にexportsを必要としません。すべては、exportISは環境に値をコピーしない-しかし、彼らも同様に環境変数として定義されているかどうかにかかわらず、シェル変数として彼らをしている存在。さらに、不要な環境変数を定義すると、それらが同じ(制限された)プロセスごとのスペースに格納されるため、コマンドラインの最大長が短くなります。
Charles Duffy 2017

回答:


21

サブシェルを使用する(推奨)

サブシェルでsourceコマンドを実行します。

(
source linuxmachines_mount_point.txt
cmd1 $linuxmachine02
other_commands_using_variables
etc
)
echo $linuxmachine01  # Will return nothing

サブシェルは括弧で定義されます:(...)。サブシェル内で設定されたシェル変数は、サブシェルが終了すると忘れられます。

unsetの使用

これにより、によってエクスポートされた変数の設定が解除されlinuxmachines_mount_point.txtます。

unset $(awk -F'[ =]+' '/^export/{print $2}' linuxmachines_mount_point.txt)
  • -F'[ =]+' スペースと等号の任意の組み合わせをフィールド区切り文字として使用するようにawkに指示します。

  • /^export/{print $2}

    これはawkに、最初の行を選択しexportて2番目のフィールドを出力するように指示します。

  • unset $(...)

    これは内$(...)でコマンドを実行し、そのstdoutをキャプチャし、その出力で指定された変数を設定解除します。


なぜこれを使わないのですか-`awk '{print $ 2}'ファイルのfor i | awk -F "=" '{print $ 1}' `; $ iの設定を解除します。できた?(unsetの方が簡単)
yael 2017

2
@yaelどちらも不要な場合は、追加のプロセスとループを使用します。意見はさまざまかもしれませんが、私はそれがより単純であるとは思いません。また、潜在的に危険ですが、すべての行fileがexportステートメントであると想定しています。
John1024

8
@yaelまた、変数の設定を解除し、他のコードの副作用を取り消すことは、まさにサブシェルの目的です。彼らはそれを簡単かつ確実に行います。それ以外の特別な理由がない限り、サブシェルは使用すべきものです。
John1024

4

sourceスクリプトを元に戻すことはできません。

あなたができることは、一時ファイルにエクスポートされたすべての変数を保存し、スクリプトが供給された後に変数と比較し、次にでオーバーフローを削除することunsetです:例:

export > temp_file
source myscript

#... do some stuff

unset "$(comm -3 <(sort temp_file) <(export | sort) | awk -F'[ =]' '{print $3}' | tr '\n' ' ')"

なぜこれを使わないのですか-`awk '{print $ 2}'ファイルのfor i | awk -F "=" '{print $ 1}' `; $ iの設定を解除します。できた?(unsetの方が簡単)
yael 2017

@yaelスクリプトがexports のみを含む場合にのみ機能します。
jimmij 2017

"export s"の意味、私のファイルにはlinuxmachine01 = "sdb sdc sdf sdd sde sdg"などが含まれています
。awk

@yael私はあなたのファイルがどのように見えるかわからないので、たとえば、スクリプトに「#マウントポイントでエクスポートする変数があります」というコメントが上部に含まれている場合など、一般的な回答をしました。
jimmij 2017

2

unsetコマンドを使用して変数を「忘れる」ことができます。


ファイルはdiffマシンにある可能性があるので、ファイルの2番目の変数の設定を解除するにはどうすればよいですか?
yael 2017

unset variablenameはそれを忘れます(bash / sh / ksh / zshのmanページで説明されています)デモ:pastebin.com/MGQyTZEA
francois P

はい。ただし、変数はdiffである可能性があるため、bashスクリプトはファイルから変数を読み取って設定を解除する必要があります。変数が不明であるため、静的にすることはできません
yael

:その後、grepのあなたは、未設定の例に名前のようにあなたを得るlinuxmachine06 =「SDB SDE自衛隊SDD」未設定の輸出linuxmachine06するファイルからリスト変数にライン(カット)をエクスポートpastebin.com/M9eCtLc7あなたがここにDOENをunsetコマンドを参照してくださいと変数名がわからない
フランソワP

設定を解除するには、この構文を使用します-for i for awk '{print $ 2}' file | awk -F "=" '{print $ 1}' `; $ iの設定を解除します。完了
yael 2017

2

期待する出力(何もない)を得る最も簡単な解決策は、変数を空として再宣言することです。

$ export linuxmachine01="sdb sdc sdf sdd sde sdg"
$ echo "$linuxmachine01"
sdb sdc sdf sdd sde sdg

$ linuxmachine01=""
$ echo "$linuxmachine01"
$

もちろん、変数はまだ定義(およびエクスポート)されており、空ですが定義されています。

$ declare -p linuxmachine01
declare -x linuxmachine01=""

環境と実行中のシェルの両方から変数を正しく削除するには、unsetを使用する必要があります(推奨される方法)。

$ unset linuxmachine01
$ declare -p linuxmachine01
bash: declare: linuxmachine01: not found
$ echo "$linuxmachine01"
$

1

これを行う最も簡単な方法は、スクリプトを変更して、スクリプトの効果を元に戻すコマンドも定義することです。

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"
alias linuxmachines_mount_point='for v in linuxmachine01 linuxmachine02 linuxmachine03 linuxmachine04; do unset $v; done; unalias linuxmachines_mount_point'

関数ではなくエイリアスを使用する理由 エイリアスは非対話型のシェルではデフォルトで無効になっているため、そのままではスクリプトでは機能しないことに注意してください。
Charles Duffy 2017

...実際、これは、変数を1つだけ定義して、設定を解除できる変数が1つだけの場合はさらに簡単になります。declare -A linuxmachines=( [01]="sdb sdc sdf" [02]="sde sdd sdb" [03]="whatever" )それunset linuxmachinesから、元に戻すだけです。
Charles Duffy 2017

@CharlesDuffy:この目的には、エイリアスと関数の両方で問題ありません。すべてを1つの変数に入れることをお勧めしないのは、元に戻すコマンドを定義する方がはるかに一般的だからです。変数だけでなく、関数、エイリアス、システム設定、端末設定なども定義解除できます。元に戻すコマンドの正確な内容を気にする必要がないため、抽象化が向上します。
リーライアン

上記の私のポイントは、「目的」に非インタラクティブな使用(つまり、スクリプトからの呼び出し)が含まれている場合、エイリアス目的にとって適切ではないということです。
Charles Duffy 2017

0

このようにlinuxmachines_mount_point.txtを書くことができます

test "$linuxmachine01" && unset -v linuxmachine01 || linuxmachine01="sdb sdc sdf sdd sde sdg"

変数が必要なとき

source linuxmachines_mount_point.txt

変数を削除したいとき

source linuxmachines_mount_point.txt

0

sourceコマンドを使用してをアクティブ化しているVirtualEnvironment場合は、コマンドを使用して終了できますdeactivate

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