スクリプト内のBashスクリプトファイルの名前を確認するにはどうすればよいですか?
スクリプトがfileにある場合、runme.sh
ハードコーディングせずに「You are running runme.sh」メッセージを表示するにはどうすればよいですか?
スクリプト内のBashスクリプトファイルの名前を確認するにはどうすればよいですか?
スクリプトがfileにある場合、runme.sh
ハードコーディングせずに「You are running runme.sh」メッセージを表示するにはどうすればよいですか?
回答:
me=`basename "$0"`
シンボリックリンク1を読むには、これは通常必要なものではありません(通常、この方法でユーザーを混乱させたくない)ので、次を試してください。
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
IMO、それは混乱する出力を生成します。「foo.shを実行しましたが、bar.shを実行していると言っています!?バグであるに違いありません!」さらに、異なる名前のシンボリックリンクを作成する目的の1つは、それが呼び出された名前に基づいて異なる機能を提供することです(一部のプラットフォームではgzipとgunzipを考えてください)。
1つまり、ユーザーfoo.sh
が実際にへのシンボリックリンクである実行時にシンボリックリンクを解決するにはbar.sh
、解決された名前bar.sh
ではなくを使用する必要がありますfoo.sh
。
$0
最初の例は単語分割の対象$0
です。3。コマンドラインスイッチとして処理できる位置でbasename、readlink、echoに渡されます。。代わりにme=$(basename -- "$0")
、読みやすさを犠牲にして、より効率的にお勧めしme=${0##*/}
ます。シンボリックリンクの場合、me=$(basename -- "$(readlink -f -- "$0")")
gnu utilsを想定しています。それ以外の場合、ここでは記述しない非常に長いスクリプトになります。
# - - - - - - - 脚本 - - - - - - - #
#!/bin/bash
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 ----------------------> $1 "
echo "# \$2 ----------------------> $2 "
echo "# path to me ---------------> ${0} "
echo "# parent path --------------> ${0%/*} "
echo "# my name ------------------> ${0##*/} "
echo
exit
#------------- CALLED -------------##------------- CALLED -------------#
#次の行に注目してください。最初の引数はdouble内で呼び出されます。 #次の行に注目してください。最初の引数はdouble内で呼び出されます。
#と単一引用符、2つの単語が含まれているため#と単一引用符、2つの単語が含まれているため
$ /misc/shell_scripts/check_root/show_parms.sh "'hello there'" "'william'"/ miscの/ shell_scripts / check_root / show_parms 。sh 「こんにちは」「ウィリアム」
# - - - - - - - 結果 - - - - - - - ## - - - - - - - 結果 - - - - - - - #
#---> 'hello there' 'william'で呼び出される引数#---> 'hello there' 'william'で呼び出される引数
#$ 1 ----------------------> 'こんにちは'#$ 1 ----------------------> 'こんにちは'
#$ 2 ----------------------> 'william'#$ 2 ----------------------> 'william'
#私へのパス--------------> /misc/shell_scripts/check_root/show_parms.sh#私へのパス--------------> /misc/shell_scripts/check_root/show_parms.sh
#親パス-------------> / misc / shell_scripts / check_root#親パス-------------> / misc / shell_scripts / check_root
#私の名前-----------------> show_parms.sh#私の名前-----------------> show_parms.sh
# - - - - - - - 終わり - - - - - - - ## - - - - - - - 終わり - - - - - - - #
show_params
、つまりオプションの拡張子のない名前を取得できますか?
${0##*/}
ます。GitBashを使用してテストされています。
bash> = 3つの以下の作品:
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s
$ cat s
#!/bin/bash
printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"
dirname $BASE_SOURCE
」を使用してスクリプトが配置されたディレクトリを簡単に取得できます。
$BASH_SOURCE
スクリプトを調達するときに正しい答えを与えます。
ただし、これにはパスが含まれているため、スクリプトのファイル名のみを取得するには、以下を使用します。
$(basename $BASH_SOURCE)
. <filename> [arguments]
、$0
呼び出し元のシェルの名前が表示されるため、この答えはより価値があると私は信じています。確かに少なくともOSXでは。
スクリプト名にスペースが含まれている場合、より堅牢な方法は、"$0"
または"$(basename "$0")"
-またはMacOS上で使用することです"$(basename \"$0\")"
。これにより、名前が壊れたり解釈されたりするのを防ぎます。一般に、シェルでは常に変数名を二重引用符で囲むことをお勧めします。
パスなしでそれが欲しいなら、あなたは使うでしょう ${0##*/}
Linuxで(少なくとも)Chris Conwayに答えるには、次のようにします。
echo $(basename $(readlink -nf $0))
readlinkは、シンボリックリンクの値を出力します。シンボリックリンクでない場合は、ファイル名を出力します。-nは、改行を印刷しないように指示します。-fは、リンクを完全にたどるように指示します(シンボリックリンクが別のリンクへのリンクだった場合、それも解決します)。
ファイルがソースであるかスクリプトで実行されているかに関係なく、この行は常に機能することがわかりました。
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
readlink
上に到達したパスでシンボリックリンクをたどる場合は、再帰的または非再帰的に使用します。
ワンライナーが機能する理由は、BASH_SOURCE
環境変数とその関連付けの使用によって説明されますFUNCNAME
。
BASH_SOURCE
FUNCNAME配列変数内の対応するシェル関数名が定義されているソースファイル名をメンバーとする配列変数。シェル関数$ {FUNCNAME [$ i]}はファイル$ {BASH_SOURCE [$ i]}で定義され、$ {BASH_SOURCE [$ i + 1]}から呼び出されます。
FUNCNAME
現在実行呼び出しスタックにあるすべてのシェル関数の名前を含む配列変数。インデックス0の要素は、現在実行中のシェル関数の名前です。一番下の要素(最高のインデックスを持つ要素)は「メイン」です。この変数は、シェル関数の実行中にのみ存在します。FUNCNAMEへの割り当ては効果がなく、エラーステータスを返します。FUNCNAMEが設定されていない場合、その後リセットされても、特殊なプロパティは失われます。
この変数は、BASH_LINENOおよびBASH_SOURCEで使用できます。FUNCNAMEの各要素には、BASH_LINENOおよびBASH_SOURCEに対応する要素があり、呼び出しスタックを記述します。たとえば、$ {FUNCNAME [$ i]}がファイル$ {BASH_SOURCE [$ i + 1]}から行番号$ {BASH_LINENO [$ i]}で呼び出されました。組み込みの呼び出し元は、この情報を使用して現在の呼び出しスタックを表示します。
[出典:バッシュマニュアル]
a
(a
のコンテンツがであると想定)でソースを取得すると機能しますecho "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
-次に、a
パスが表示されます。しかし、スクリプトb
を記述source a
して実行すると./b
、b
のパスが返されます。
これらの回答は、記載されているケースでは正しいですが、「source」キーワードを使用して別のスクリプトからスクリプトを実行すると(同じシェルで実行されるように)、依然として問題があります。この場合、呼び出しスクリプトの$ 0を取得します。この場合、スクリプト自体の名前を取得することはできないと思います。
これはエッジケースであり、真剣に受け止めるべきではありません。別のスクリプトからスクリプトを直接(「ソース」なしで)実行する場合は、$ 0を使用できます。
Re:上記のTanktalusの(受け入れられた)答えは、少しすっきりとした方法を使用することです。
me=$(readlink --canonicalize --no-newline $0)
スクリプトが別のbashスクリプトから供給されている場合は、以下を使用できます。
me=$(readlink --canonicalize --no-newline $BASH_SOURCE)
あなたの目的がユーザーにフィードバックを提供することである場合、シンボリックリンクを逆参照することは混乱を招くことに同意しますが、正規の名前をスクリプトまたは他のファイルに取得する必要がある場合がありますが、これが最善の方法です、imo。
source
dスクリプト名をお寄せいただきありがとうございます。
あなたのようなシェルスクリプトを呼び出す場合
/home/mike/runme.sh
$ 0はフルネームです
/home/mike/runme.sh
basename $ 0はベースファイル名を取得します
runme.sh
そして、この基本的な名前を次のような変数に入れる必要があります
filename=$(basename $0)
追加のテキストを追加します
echo "You are running $filename"
だからあなたのようなスクリプト
/home/mike/runme.sh
#!/bin/bash
filename=$(basename $0)
echo "You are running $filename"
this="$(dirname "$(realpath "$BASH_SOURCE")")"
これにより、シンボリックリンクが解決され(realpathがそれを実行)、スペースが処理され(二重引用符で処理されます)、ソース(。./myscript)または他のスクリプトから呼び出された場合($ BASH_SOURCEが処理する)でも、現在のスクリプト名が見つかります。結局のところ、これを環境変数に保存して、再利用したり、他の場所に簡単にコピーしたりできます(this =)...
realpath
は組み込みのBASHコマンドではありません。これは、特定のディストリビューションでのみ使用可能なスタンドアロンの実行可能ファイルです
$0
(私が理解しているように)質問に答えません。デモ:
$ cat script.sh #!/ bin / sh echo `basename $ 0` $ ./script.sh script.sh $ ln script.sh linktoscript $ ./linktoscript linktoscript
どうすれば./linktoscript
印刷できscript.sh
ますか?
[編集]上記のコメントの@ephemientによると、シンボリックリンクは不自然に見えるかもしれ$0
ませんが、ファイルシステムリソースを表さないようにいじることは可能です。OPは彼が何を望んでいたかについて少し曖昧です。
情報はBill Hernandezに感謝します。採用している設定をいくつか追加しました。
#!/bin/bash
function Usage(){
echo " Usage: show_parameters [ arg1 ][ arg2 ]"
}
[[ ${#2} -eq 0 ]] && Usage || {
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 -----------------------> $1 "
echo "# \$2 -----------------------> $2 "
echo "# path to me ---------------> ${0} " | sed "s/$USER/\$USER/g"
echo "# parent path --------------> ${0%/*} " | sed "s/$USER/\$USER/g"
echo "# my name ------------------> ${0##*/} "
echo
}
乾杯
短く、明確でシンプル、 my_script.sh
#!/bin/bash
running_file_name=$(basename "$0")
echo "You are running '$running_file_name' file."
出力:
./my_script.sh
You are running 'my_script.sh' file.
DIRECTORY=$(cd `dirname $0` && pwd)
上記は別のスタックオーバーフローの質問から取得しました。Bashスクリプトは、それが格納されているディレクトリを確認できますか?ですが、このトピックにも役立ちます。
これが私が思いついたもので、Dimitre Radoulovの回答(ちなみに私は賛成しています)に触発されています。
script="$BASH_SOURCE"
[ -z "$BASH_SOURCE" ] && script="$0"
echo "Called $script with $# argument(s)"
スクリプトを呼び出す方法に関係なく
. path/to/script.sh
または
./path/to/script.sh
このような何か?
export LC_ALL=en_US.UTF-8
#!/bin/bash
#!/bin/sh
#----------------------------------------------------------------------
start_trash(){
ver="htrash.sh v0.0.4"
$TRASH_DIR # url to trash $MY_USER
$TRASH_SIZE # Show Trash Folder Size
echo "Would you like to empty Trash [y/n]?"
read ans
if [ $ans = y -o $ans = Y -o $ans = yes -o $ans = Yes -o $ans = YES ]
then
echo "'yes'"
cd $TRASH_DIR && $EMPTY_TRASH
fi
if [ $ans = n -o $ans = N -o $ans = no -o $ans = No -o $ans = NO ]
then
echo "'no'"
fi
return $TRUE
}
#-----------------------------------------------------------------------
start_help(){
echo "HELP COMMANDS-----------------------------"
echo "htest www open a homepage "
echo "htest trash empty trash "
return $TRUE
} #end Help
#-----------------------------------------------#
homepage=""
return $TRUE
} #end cpdebtemp
# -Case start
# if no command line arg given
# set val to Unknown
if [ -z $1 ]
then
val="*** Unknown ***"
elif [ -n $1 ]
then
# otherwise make first arg as val
val=$1
fi
# use case statement to make decision for rental
case $val in
"trash") start_trash ;;
"help") start_help ;;
"www") firefox $homepage ;;
*) echo "Sorry, I can not get a $val for you!";;
esac
# Case stop