echo
Bash 3.2.52では、環境ではないすべての変数(すべての独自の宣言変数)が必要です。
すべての変数を印刷するこのコマンドは、私が理解できない出力を提供し、私の考えでは、私がすでにset -x && clear -r
作業しているパターンと衝突します。
diff -U 1 <(set -o posix ; set |cut -d= -f1) <(
exec bash -ic 'set -o posix ; set' | cut -d= -f1) |
grep '^[-][^-]' |
cut -d- -f2 |
grep -vE '^(COLUMNS|HISTFILESIZE|HISTSIZE|LINES|PIPESTATUS)$'
echo
そのようなリストを取得するにはprintf
(または他の「より簡単な」)作業が必要です。
このバージョンのBashで可能であれば、どのように達成できますか?
答え1
GNU Parallel Includeenv_parallel
セクションには、env_parallel
サポートされているシェルのすべての変数がリストされています。
このコードの場合はbash
次のようになります。
_names_of_VARIABLES() {
compgen -A variable
}
_bodies_of_VARIABLES() {
typeset -p "$@"
}
したがって、すべての変数が与えられたら、ユーザーがどの変数を設定したかを調べる必要があります。私たちできるこれは特定のバージョンのすべての変数をハードコードすることによって行われますが、将来のバージョン(ユーザーまたは将来のバージョン?)でより多くの変数が設定される可能性があるため、bash
これは将来の証拠ではありません。bash
$BASH_MYVAR
bash
したがって、env_parallel
クリーンな環境を定義し、env_parallel --session
その中で実行する必要があります。これは$PARALLEL_IGNORED_NAMES
、以前に定義された名前をリストして設定されます(上記のコードを使用)。
後でユーザーが変数を設定した環境で実行してみると、クリーン環境と現在の環境の違いが簡単にわかります。
env_parallel --session
セッションごとにきちんとした環境を定義することは可能ですが、セッション全体で使用できる参照環境が必要な場合は、変数のリストをファイルに保存できます。だから:
# In clean envronment
compgen -A variable > ~/.clean-env-vars
# In environment with user defined vars
compgen -A variable | grep -Fxvf ~/.clean-env-vars
たとえば、
#!/bin/bash
# In clean envronment
compgen -A variable > ~/.clean-env-vars
myvar=4
yourvar=3
# In environment with user defined vars
compgen -A variable | grep -Fxvf ~/.clean-env-vars
# This prints:
# myvar
# yourvar
# PIPESTATUS (which is set when running a pipe)
答え2
これをあなたの~/.bashrc
pre () {
set -o posix;set > /tmp/tmp-original-envs
}
post () {
set -o posix;set > /tmp/tmp-new-envs
diff /tmp/tmp-original-envs /tmp/tmp-new-envs | grep -v BASH_LINENO | grep -v FUNCNAME | grep '>'
}
pre
その後、修正の前後にpost
実行してください。
例:
[localhost]$ pre
[localhost]$ test=new
[localhost]$ post
> test=new
[localhost]$
答え3
必要に応じて簡単な解決策は次のとおりです。
- 変更する前に、
set > tmp
現在の変数を使用または保存してください。set > /tmp/current
- アプリケーションを修正/実行しますか?
diff -u <(cat tmp) <(set)
またはで変更されたコンテンツの抽出
diff -u <(cat tmp) <(set) | tail -n +3 | grep -v PIPESTATUS | grep -v "_=" | grep -E "^\+"
どこ:
tail -n +3
:diff コマンドの最初の行から不要な行を削除します。
grep -v PIPESTATUS | grep -v "_="
: 不要な変数の削除
grep -E "^\+"
:希望/必要な変更のみを表示
選択する:
diff -u <(set -o posix; set) <(bash -lc 'set -o posix; set') | grep -E "^\+"
メモ:
スクリプトでexec
開始されたプロセスを完全に置き換えると、達成しようとしている作業が妨げられる可能性があることに注意してください。
答え4
不器用なbash専用ソリューション:
(setn(){
set | sed '/^{/,/^}/d;/=/!d;/^BASH[A-Z_]*=\|^PPID=\|^SHLVL=\|^PIPESTATUS=\|^HISTSIZE=\|^HISTFILESIZE=\|^_[a-z_]*=/d' | sort
}
export -f setn
comm -23 <(setn) <("$BASH" -ic setn))
また、他の変数をフィルタリングする必要があるかもしれませんsed
(またはパターンをより制限的に作成する必要があるかもしれません)。あるいは、などのプログラム可能な完成として定義された変数は除外するBASH..
必要があります。これはより制限的です。 /_[a-z_]*=/
_backup_glob
_xspecs
bash
型に興味深い文字を含む変数値が印刷されるため、$'...'
これを処理する必要があります。
foo='
bar
baz
'
...
foo=$'\nbar\nbaz\n'
bash
シェル変数は envvar では生成されません。名前改行文字が含まれているので、このようなトリックでこのハッキングを復号する方法はありません。