スペースを含むパスを引数として渡す

スペースを含むパスを引数として渡す

スペースを含む一部の文字列変数をパラメータとしてプログラムに渡すのが困難です。
渡される引数をデバッグして表示するためのデモ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シェルセッションの進行中に、以前のシンボリックリンクディレクトリの変更によって暗示されたすべての間接パスが維持されます。

したがって、ツリーを巡回すると、ツリー内の名前を最も確実に収集できます。

関連情報