スペースを含む一部の文字列変数をパラメータとしてプログラムに渡すのが困難です。
渡される引数をデバッグして表示するためのデモPythonスクリプトを作成しました。
##### show_args.py #####
import sys
def main():
# Display the arguments passed to the script
print "Number of arguments =", len(sys.argv)
for arg in sys.argv:
print arg
if __name__ == '__main__':
main()
ここで問題を示すスクリプトは次のとおりです。
path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc $path_with_spaces/xyz"
python show_args.py $arg_list
出力 -:
Number of arguments = 5
show_args.py
/home/anmol/blah
blah/abc
/home/anmol/blah
blah/xyz
私が本当に欲しいのはこれです - :
path_with_spaces="$HOME/blah blah"
python show_args.py "$path_with_spaces/abc" "$path_with_spaces/xyz"
出力 -:
Number of arguments = 3
show_args.py
/home/anmol/blah blah/abc
/home/anmol/blah blah/xyz
スペースがあるパスでのみ問題が発生するかどうかを確認するために、次のスクリプトを作成しました。
path_without_spaces="$HOME/blah"
arg_list="$path_without_spaces/abc $path_without_spaces/xyz"
python show_args.py $arg_list
出力 -:
Number of arguments = 3
show_args.py
/home/anmol/blah/abc
/home/anmol/blah/xyz
この問題に対する解決策を見つけて、偶然発見しました。この回答この方法によると、正しい方法はパラメータを文字列変数の代わりに配列変数に入れることです。
この新しいアプローチを示すスクリプト - :
path_with_spaces="$HOME/blah blah"
arg_list=("$path_with_spaces/abc" "$path_with_spaces/xyz")
python show_args.py "${arg_list[@]}"
出力 -:
Number of arguments = 3
show_args.py
/home/anmol/blah blah/abc
/home/anmol/blah blah/xyz
このソリューションは正常に動作しますが、配列変数の代わりに文字列変数を使用して同じことを行う方法があるかどうかはまだ疑問に思います。
私のシステム構成 -:
- Ubuntu 14.04 LTS
- ヘビーストライク 4.3.11
- GNOME端末3.6.2
答え1
存在する:
path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc $path_with_spaces/xyz"
python show_args.py $arg_list
スカラー/文字列変数を使用しています。分割+グローバル演算子(変数の引用解除)は、変数の内容を分割して渡す引数を生成しますpython
。
これ分ける~の一部分割+グローバル演算子は特殊引数に格納されている文字を分割します$IFS
。
ここで無効にすることができます全体的な状況パスに見つからない文字を分割して分割します。例えば、新しいチーム次のパスに見つかりません。
path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc
$path_with_spaces/xyz"
IFS="
"
set -f # disable glob.
python show_args.py $arg_list
eval
また、シェル引用符を使用し、シェルがこれらの引用符を解釈できるようにすることもできます(bash
ここでは特定の機能が使用されます)。
printf -v arg_list '%q ' "$path_with_spaces/abc" \
"$path_with_spaces/xyz"
eval "python show_args.py $arg_list"
答え2
はい。
デフォルトのパス区切り文字を使用してパスを区切ることができます。パス名に2つの無効な文字があります。
\0NUL
性格パス
/
区切り記号
偶然にも、シェルのパス名を区別できます。内部フィールド区切り記号 $IFS
特殊パラメータ。複数の区切り文字が順番に表示されると、結果コンポーネントはパス名になることが\0NUL
できない値引数になります。
機能するには、すべてのパスを直接ルーティングする必要があります。(したがってルートを除く//
)、標準パスがあることを確認する必要があります。それ以外の場合、少なくともすべてのパスが//*
各パスに一度表示されるように圧縮されます。(ポイントは病気ではありません - または役に立ちます)。これを行うと:
paths='/path/one//path/t w o//p a t h/t h r e e/'
set -f --; IFS=/
for p in ${paths#/}$IFS
do printf ${p:+/}%s\\n "$*"
set -- ${p:+"$@"/$p}
done
/path/one
/path/t w o
/p a t h/t h r e e
$PWD
を使用して正規パスを取得できますcd
。
cd -- /some//../screwy/../path/to///destination
printf %s\\n "$PWD"
/path/to/destination
を使用すると、-P
このスイッチはcd
現在の作業ディレクトリへの絶対物理パスがに設定されるようにします$PWD
。それ以外の場合、-L
またはデフォルトでは、cd
シェルセッションの進行中に、以前のシンボリックリンクディレクトリの変更によって暗示されたすべての間接パスが維持されます。
したがって、ツリーを巡回すると、ツリー内の名前を最も確実に収集できます。