0

システムが提供する は複数のソースを受け入れないため、bashオプションをサポートしないが のように動作するスクリプトを作成するとします。cpcp

システムの使用法 (仮想および壊れたもの)cpは次のとおりです。

cp source target    # target may be a directory

スクリプトの使用法は次のとおりです。

cp.sh source... target    # target must be a directory

スクリプトの開始点は次のとおりです。

#!/bin/bash
tgt="$1"
shift
for src in "$@"; do
    echo cp $src $tgt
done

引数 " " (がターゲットであることにa b c d注意してください) を指定して実行すると、次のように出力されます。d

cp b a
cp c a
cp d a

目標は、コードをシンプルに保ちながら、代わりにこれを出力するようにスクリプトを修正することです。

cp a d
cp b d
cp c d
4

8 に答える 8

5

/test.bash ソース1 ソース2 ターゲット1

#!/bin/bash

target=${!#} 

if [ ! -d $target ] ; then
    echo "$target must be a directory " >&2
    exit 1;
fi

args=("$@")
unset args[${#args[@]}-1]

for src in "${args[@]}"; do
    echo cp $src $target
done

出力します

cp source1 target1
cp source2 target1
于 2009-09-22T18:59:25.433 に答える
2

配列スライスを使用して、最後の引数を除外できます。

tgt="${!#}"
for src in "${@:1:$#-1}"; do
    cp "$src" "$tgt"
done
于 2009-09-23T15:31:13.827 に答える
1

なんで?cp コマンドはすでにそれを行っています。man cpを実行すると表示されます。

それでも主張する場合は、最後の引数を取得する 2 つの方法を次に示します。方法 1: コマンド ラインを配列に配置し、最後の要素を抽出します。

arg=("$@")
last_arg=${arg[(($# - 1))]}

最初の行は、コマンド ライン引数を配列 arg に入れます。コマンド ラインにabcdが含まれている場合は、arg[0] == 'a', ... argv[3] == 'd' となります。

2 行目は、最後の引数を抽出します。(($# - 1)) は引数の数 (この場合は 4) を取り、そこから 1 を引きます (3 を取得します)。その式は次のようになります。

last_arg=${arg[3]}

これは最後の引数を指します。


2 番目の方法はあまり移植性がありません。BASH_ARGV 変数を使用します。これは $@ ですが、順序が逆です。コマンドラインがabcdの場合、 ${BASH_ARGV[0]} == 'd', ... ${BASH_ARGV[3]} == 'a':

last_arg=${BASH_ARGV[0]}

これが役立つことを願っています。

于 2009-09-22T17:55:17.397 に答える
1
#!/bin/bash
tgt="${@: -1}"    # get the last parameter
for src in "$@"; do
    if [[ $src != $tgt ]]; then
        echo cp "$src" "$tgt"
    fi
done
于 2009-09-22T18:16:36.940 に答える
0

xargsを使用してスクリプトを記述せずに、これを直接行うことができます。

echo source1 source2 | tr "\n" "\0" | tr " " "\0" | 
   xargs --verbose -0 -I{} cp {} dest
于 2009-09-25T19:58:47.887 に答える
0

bash固有の機能は必要ありません。

eval last = \ $ {$#}
while [$#-gt 1]; 行う
  echo "cp $ 1 $ last"
  シフト
終わり
于 2009-09-25T16:26:09.610 に答える
0
#!/bin/bash
t=(x "$@")
i=1; while [ $i -lt $# ]; do
  echo cp ${t[$i]} ${t[$#]}
  i=$(($i + 1))
done
于 2009-09-22T18:12:56.930 に答える
-1

これを使用して、最後のパラメーターを抽出します。

eval tgt=\$$#

次に、あなたと同じように処理し、 $# を押すとループを終了します

Whjole スクリプトは次のとおりです。

eval tgt=\$$#

for src in $@
do
 if [ "$src" == "$tgt" ];
 then
    exit
fi
echo cp $src $tgt
done

あなたが私に尋ねると、かなり簡単です!

于 2009-09-22T17:56:55.490 に答える