私はコマンドライン引数からディレクトリを読み込んでls
これを行うbashスクリプトを書いています。
単純なディレクトリを指定すると、すべてが正常です。
しかし、同様のことをしたいので、という変数に格納されている値を/home/{x,y}
使用してスクリプトが呼び出されます。my-script -d '/home/{x,y}'
'/home/{x,y}'
source
試してみましたが
ls "${source}"
帰ってきました。ls: cannot access /home/{x,y}: No such file or directory
試してみました
ls ${!source}
が、現在のディレクトリのファイルが返されます。試しましたが、
ls \$$source
最初のエラーで再び失敗しました。
'/home/{x,y}'
スクリプトが実行されるようにスクリプトのパラメータを拡張するにはどうすればよいですかls /home/x /home/y
?
答え1
一般的なアプローチは、オプションフラグなしでディレクトリをデフォルトのコマンドライン引数として渡すことです。つまり、ユーザーはmy-script -a -b foo /home/me/dir1 /some/other/path
構文解析オプションを実行した後、getopts
場所引数にディレクトリを保持して実行できますls "$@"
。ここでユーザーは、またはシェルで埋めることができる拡張を使用して最後の引数を埋めることができ/some/path/{foo,bar}
ます/some/path/*
。
または、ユーザーが-d
実行している項目に複数のオプションを渡すようにします。ここで拡張を使用することは、シェルが許可するすべての項目を各引数の前に追加する必要があるmy-script -a -b foo -d /home/me/dir1 -d /some/other/path
ため、より困難です。-d
たぶん同様のものがあるかもしれませんa=(/path/{this,that}); my-script -a -b foo "${a[@]/#/-d}"
。
それにもかかわらず、スクリプトからシェルの拡張を複製することは一般的ではなく、ユーザーをパニックにする可能性があるため、お勧めできません。そうすれば、あなたも決定を下す必要がありますどのサポートするように拡張されました。すべての拡張がすべてのシェルでサポートされるわけではなく、各シェルでサポートされているすべての拡張がすべてのユーザーに認識されているわけではありません。
答え2
はい.sh:
#!/usr/bin/env bash
FILE_PATTERN="$1"
MATCHING_FILES=$(eval "echo $FILE_PATTERN")
echo "Files: $MATCHING_FILES"
ls -l $MATCHING_FILES
これは example.sh の最初の引数をシェルグローブパターンとして使用します。スペースや特殊文字を含むファイル名が破損する可能性があります。パターンの適用中にこれを防ぐために変数を参照する方法は、ユーザーが見つけることです。
使用法:
$ ./example.sh 'file-{x,y}.txt'
Files: file-x.txt file-y.txt
-rw-r--r-- 1 user group 0 30 Sep 16:47 file-x.txt
-rw-r--r-- 1 user group 0 30 Sep 16:47 file-y.txt
可能であれば、なるべくいいえこれを行い、複数のファイル名を引数として受け入れます。確かに、変数参照はより明確で簡単になり、globパターンのように見えるファイル名に対するStéphaneの問題を処理することを避けることができます。
答え3
私はそれをします:
#! /bin/bash -
sources=()
while getopts d:... o; do
case $o in
(d) sources+=("$OPTARG");;
(...) ;;
esac
done
shift "$((OPTIND - 1))"
ls -- "${sources[@]}"
つまり、呼び出し元が-d
各ディレクトリに1つのディレクトリを使用するディレクトリのリストをスクリプトから取得するようにします。
これにより、ユーザーは次の操作を実行できます。
my-script -d/home/{x,y}
シェルが中括弧拡張をサポートするのか、シェルがこのリストを作成するのに役立つ機能を提供するのか。
rc
// では、fish
次zsh -o rcexpandparam
のようになります。
my-script -d$array
例えば(inなし-d$^array
でも可能)rcexpandparam
zsh
存在するzsh
:
my-script /home/*(P[-d])
など。
スクリプトが他の形式の拡張ではなく引数の中括弧拡張を実行するようにするには、(スタイル文字を許可したい場合)を除くすべての{
文字}
シーケンスを引用して実行できます。,
.0-9
{1..10}
eval
zsh
これは使いやすく、機能が非常に制限されているksh93
ためです。bash
${var//pattern/replacement}
#! /bin/zsh -
source=${1?}
set -o extendedglob
eval "sources=( ${source//(#m)[^"{}".,0-9]##/'$MATCH'} )"
printf ' - "%s"\n' "$sources[@]"
例:
$ myscript 'x\{1..3}$$`{a b,c}'
- "x\1$$`a b"
- "x\1$$`c"
- "x\2$$`a b"
- "x\2$$`c"
- "x\3$$`a b"
- "x\3$$`c"
ただし、ユーザーはリテラルfoo{a,b}
パラメータを渡すことができなくなります。
答え4
これは、1つではなく複数のパラメータで評価されるために発生します。この試み:
ls "$@"
$@
すべてのパラメータをスペースで区切られた文字列に展開します。