シンボリックリンクを介してファイルを処理するbash関数:コマンドラインパラメータの問題

シンボリックリンクを介してファイルを処理するbash関数:コマンドラインパラメータの問題

私は与えられた名前またはシンボリックリンクを持つファイルを与えられたディレクトリにコピーするコードを書いた。

linkcp() {
cp `echo "$(realpath $1)"` "$2"
}

ファイルのリストは次のとおりです。

$ ls -l
drwxr-xr-x 2 user1 users 4096 apr. 30 01:20 temp
-rw-r--r-- 1 user1 users 50 apr. 30 01:20 file1
-rw-r--r-- 1 user1 users 34 apr. 30 01:20 file2
lrwxrwxrwx 1 user1 users 26 apr. 30 01:20 lnk1 -> file1
lrwxrwxrwx 1 user1 users 26 apr. 30 01:20 lnk2 -> file2

以下を使用すると機能します。

$ linkcp lnk1 temp
$ ls temp/
$ file1

ただし、ワイルドカードを使用している場合はそうではありません(lnkで始まるすべてのファイルを移動する必要があります)。

$ rm temp/*
$ linkcp lnk* temp
$ ls temp/
$

私がするなら:

$ arg=lnk*
$ cp `echo "$(realpath $arg)"` "temp/"
$ ls temp/
$ file1  file2

$1関数で使用するのになぜ問題があるのか​​わかりません。

ベストアンサー1

Haukeが指摘したように、問題は2つのパラメータを期待していましたが、関数に複数のパラメータを提供したことです。link*これは関数に渡される前にシェルによって拡張されるため、実際に実行されているのは次のとおりです。

linkcp lnk1  lnk2  temp

lnk*に拡張されるからですlnk1 lnk2

だから、あなたが本当に欲しいのはこれです:

linkcp() {
    ## Save the arguments given to the function in the args array
    args=("$@");

    ## The last element of the array is the target directory
    target=${args[((${#args[@]}-1))]}

    ## If the target  is a directory
    if [ -d "$target" ];
    then
    ## Iterate through the rest of the arguments given
    ## and copy accordingly
    for((i=0; i<$#-1; i++))
    do
        cp -v "$(realpath "${args[$i]}")" "$target"
    done
    ## If the target does not exist or is not a directory, complain
    else
    echo "$target does not exist or is not a dirtectory" 
    fi
}

おすすめ記事