シェルスクリプトの$ {0%/ *}は何をしますか?


17

これが愚かな質問であれば申し訳ありませんが、私はそれについて検索しましたが成功しませんでした。

正確に2行目は何をしますか?:

#!/bin/sh
cd ${0%/*} || exit 1

最初はシェバンで、2番目はディレクトリを変更しようとしますが、混乱する部分は${0%/*}です。

二行目を説明してもらえますか?


2
Andreaが回答で説明したように、$ {0%/ *}は、スクリプト名を呼び出すときに、スクリプト名の前に付けられたディレクトリパスに変換されます。別の方法は、dirname次のような組み込みコマンドを使用することです$(dirname $0)
-alwayslearning

@alwayslearning:dirname組み込まれているシェルとシェルのバージョンは何ですか?確かに、Ubuntu TrustyのデフォルトのシェルであるBash v4.3.11にはありません。
デビッドフォースター

混乱をおdirnameaびします。シェルビルトインではないことを確認しました。
常に学習する

回答:


27

${0}スクリプトの最初の引数、つまりスクリプト名またはパスです。スクリプトをとして起動するとpath/to/script.sh${0}まさにその文字列になりますpath/to/script.sh

%/*一部には、の値を変更します${0}。つまり/、ファイル名が続くまですべての文字を使用します。上記の例で${0%/*}は、になりますpath/to

シェルで実際にそれを見ることができます:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Shは、他の多くの種類の「パラメーター置換」をサポートしています。たとえば、パスではなくファイル名を取得する方法は次のとおりです。

$ echo "${x##*/}"
script.sh

一般的に、%および%%接尾辞を除去し、while #および##strip接頭辞を除去します。詳しく読むことができますパラメーターの置換


2
この「|| exit 1」は不要なようです。どうしてもdir $を変更する必要がありますか?1に等しい
ヨーゼフクリムク

2
このコンストラクトは、マニュアルで「一致するプレフィックス/サフィックスパターンの削除」として文書化されていることに言及しておくと便利です。また、少なくともUSキーボードでは、どちらが#がシフト3($の)で、%がシフト5($の)であるかを覚えるのに良い方法です。
chexum

1
@JosefKlimuk:エラー時に1ではなくステータス2で終了する|| exit 1 可能性があるためcd、しかし、あまり有用ではないことに同意します(通常、プログラムは特定の終了ステータスを気にしません)。おそらくこれは大きなスクリプトの一部ですか?
アンドレアコルベッリーニ

1
@AndreaCorbellini確かに正しい。かなり便利な方法は、より大きなスクリプトの一部として使用することです。現在のディレクトリを変更するだけのスクリプトは、その1つのスクリプトを実行しているシェルにのみ影響するため、効果はありません。親プロセスはそれを見ることはありません。
hvd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.