私は素晴らしいチュートリアルとスクリプトを読んでシェルスクリプトを学びました。
私はこれを読んでいますMinecraft初期化スクリプト、最初の行は私に深い印象を残しました。
if [ -L $0 ]
then
source `readlink -e $0 | sed "s:[^/]*$:config:"`
else
source `echo $0 | sed "s:[^/]*$:config:"`
fi
したがって、この行は同じシェル(すべての設定値が保存される場所)で "config"というスクリプトを起動します。しかし、なぜファイルを直接実行するのではなく(「ソース設定」などを使用して)、スクリプトの作成者は元のスクリプトの名前(リンクであるかどうかにかかわらず)を読み取り、結果を送信してsed
その名前を置き換えます。 「構成」で?
答え1
ソースコードの使用
このコマンドはsource
他のスクリプトを実行しません。他のスクリプトの内容をこのスクリプトにインポートし、その内容が元の呼び出しスクリプトの一部であるかのように実行します。
これは基本的に、他のスクリプトの内容を自分と同じ範囲に含めるメカニズムです。
読み取りリンクの使用
このコマンドは、ソーススクリプトがリンクを介して呼び出される場合に存在します。
sedを使う
このスクリプトはsedを使用して呼び出しスクリプトの名前をnameに変換しますconfig
。
はい
次のスクリプトがあるとしますorig.bash
。
#!/bin/bash
printf "exectued as: %s\n" $0
cmd=$(readlink -e $0 | sed "s:[^/]*$:config:")
printf "sourcing as: %s\n" "$cmd"
このプログラムは2つのことを行います。
印刷された値
$0
printf "exectued as: %s\n" $0
readlink ...
印刷コマンド値cmd=$(readlink -e $0 | sed "s:[^/]*$:config:") printf "sourcing as: %s\n" "$cmd"
それでは、このスクリプトへのリンクを作成しましょうlink2orig.bash
。ディレクトリに次のファイルがあります。
# creates link
$ ln -s orig.bash link2orig.bash
# results after
$ ls -l
total 4
lrwxrwxrwx 1 saml saml 9 Sep 5 06:23 link2orig.bash -> orig.bash
-rwxrwxr-x 1 saml saml 126 Sep 5 06:31 orig.bash
今何が起こるのか見てみましょう
実際の名前またはリンクを使用してサンプルスクリプトを実行すると、文字列を呼び出し元の引数に置き換えることができますconfig
。これは、私たちが調達しているスクリプトの構成情報を含む別のファイルです。
$ ./orig.bash
executed as: ./orig.bash
sourcing as: /home/saml/tst/89518/config
$ ./link2orig.bash
executed as: ./link2orig.bash
sourcing as: /home/saml/tst/89518/config
ご存知のように、このアプローチの利点の1つは、システムのさまざまな場所でさまざまな方法で呼び出されることに非常に寛大です。
$ ../89518/orig.bash
executed as: ../89518/orig.bash
sourcing as: /home/saml/tst/89518/config
$ ../89518/link2orig.bash
executed as: ../89518/link2orig.bash
sourcing as: /home/saml/tst/89518/config
答え2
$0
スクリプトへのパスです。通常、スクリプトのフルパスです(つまり、で始まる絶対パス/
)。スクリプトが実行可能でshebang行で始まる一般的な場合、パスはフルパスになります。ただし、シェルが明示的に呼び出される場合、$0
これはユーザーがコマンドラインに入力するすべてのエントリであり、パスを含めない可能性があります(cd somedir; bash minecraft
、$0
isを使用minecraft
)。標準入力でスクリプトを使用してシェルを呼び出す場合、$0
シェルの名前またはパス(bash <minecraft
、、$0
is bash
)。
シンボリックリンクを介してスクリプトにアクセスすると、スクリプトはリンクのフルパスとreadlink
Linux関連ユーティリティを介して拡張シンボリックリンクを検索します。
名前変換はスクリプトのデフォルト名をconfig
。つまり、yesの場合$0
(またはreadlink $0
場合によっては)/path/to/minecraft
sedコマンドはを出力します/path/to/config
。パスに以下が含まれていない場合でも機能します/
。minecraft
config
スクリプトの要点は、config
スクリプトと同じディレクトリで呼び出されたファイルを見つけてそのファイルを取得することです(つまり、呼び出しスクリプトと同じコンテキストでスクリプトを読み込んで実行すること)。後でスクリプトで使用される変数をconfig
定義する設定ファイルです。minecraft
スクリプトがありません変数とコマンドの置換は二重引用符で囲まれています。。次のように書く必要があります。
if [ -L "$0" ]
then
source "$(readlink -e "$0" | sed 's:[^/]*$:config:')"
else
source "$(echo "$0" | sed 's:[^/]*$:config:')"
fi
スクリプトパスに-
改行文字が含まれているか含まれている場合はまだ失敗しますが、この場合はまれです。
シェル文字列操作構成を使用して、同じアイデア(への外部呼び出しを除くreadlink
)を作成できます。
case $0 in */*) config=$0;; *) config=./$0;; esac # make sure there is a / in $config
if [ -L "$config" ]; then config=$(readlink -e -- "$config"); fi
config=${config%/*}/config