bash組み込みコマンドをset
引数なしで呼び出すと、すべての定義された関数だけでなく、すべてのシェルと環境変数が印刷されます。これは出力を無効にし、人が使いにくくしますgrep
。
bashの組み込みset
関数が関数ではなく変数のみを印刷するにはどうすればよいですか?
関数ではなくシェル変数のみを印刷する他のコマンドはありますか?
注:bashはシェル変数と環境変数を区別します。ねえbashの環境変数とエクスポートされた環境変数の違い
答え1
「関数は出力せずにシェル変数のみを出力する他のコマンドはありますか?」
man bashのSHELL BUILTIN COMMANDSセクション(setセクション)には、「posixモードではシェル変数のみがリストされています」と記載されています。
(set -o posix; set)
注:()
構文はサブシェルを生成します。四半期が好きではない場合は、より詳細なバージョンを使用してください。
set -o posix; set; set +o posix
答え2
以下はいくつかの回避策です。
$ comm -3 <(declare | sort) <(declare -f | sort)
分解:
declare
定義されているすべての変数(エクスポートまたはエクスポートされていない)と関数を印刷します。declare -f
印刷機能のみあります。comm -3
両方に共通のすべての行が削除されます。効果的に、これは関数を削除し、変数だけを残します。
エクスポートされていない変数のみを印刷する:
$ comm -3 <(comm -3 <(declare | sort) <(declare -f | sort)) <(env | sort)
別の回避策:
$ declare -p
これにより変数のみが印刷されますが、一部の見苦しいプロパティが含まれます。
declare -- BASH="/bin/bash"
declare -ir BASHPID=""
declare -A BASH_ALIASES='()'
declare -a BASH_ARGC='()'
...
...cutを使用して属性を切り取ることができます。
$ declare -p | cut -d " " -f 3
1つの欠点は、IFSの値が表示されずに解釈されることです。
比較する:
$ comm -3 <(declare | sort) <(declare -f | sort)
...
IFS=$' \t\n'
...
$ declare -p | cut -d " " -f 3
...
IFS="
"
...
"
この出力は1行だけであるため、この出力をさらに処理するのは難しいです。これが発生しないようにIFS-fuを実行することもできます。
別の回避策は、次を使用することですcompgen
。
$ compgen -v
bash 組み込み機能は、compgen
完成スクリプトに使用するためのものです。これを行うには、定義されているcompgen -v
すべての変数をリストします。短所:値ではなく変数名のみが一覧表示されます。
これらの値をリストするコツもあります。
$ compgen -v | while read var; do printf "%s=%q\n" "$var" "${!var}"; done
利点:純粋なbashソリューションです。欠点:解釈のためにいくつかの値が混乱する可能性がありますprintf
。さらに、パイプおよび/またはループ内のサブシェルはいくつかの追加変数を追加します。
答え3
奇妙なことに、組み込み関数には引数だけを表示せず、関数typeset
()のみを表示するオプションがあります。-f
幸いなことにtypeset
(またはset
)は、すべての関数、関数、およびパラメータ名に改行や等号を含めることはできません\n
。したがって、等号を含まない最初の行で停止できます。
set | awk -F '=' '! /^[0-9A-Z_a-z]+=/ {exit} {print $1}'
これはパラメータ名のみを印刷します。値が必要な場合print $1
はに変更してくださいprint $0
。
これは、環境変数(「環境変数」は「エクスポートされたパラメータ」と同義語)だけでなく、すべてのパラメータ名(ここでパラメータと変数は同義語として使用されます)を印刷します。
また、パラメーター名に対する bash の制約と名前が一致しない環境変数がないとします。これらの変数はbashの内部で作成することはできませんが、bashの起動時に環境から継承できます。
env 'foo ()
{
=oops' bash
答え4
ただコマンドを使用してくださいenv
。機能を印刷しません。