기호 링크를 통해 파일을 처리하는 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
}

답변2

무슨 일이 일어나고 있는지 확인하려면 다음을 시도하십시오.

echo linkcp lnk* temp

linkcp2개 이상의 매개변수를 가져오되 처음 2개만 고려하세요.

다음과 같은 것이 필요합니다.

linkcp() {
  local i num=$# tmparray=()
  for((i=1;i<num;i++)); do
    tmparray[i]="$(realpath "${!i}")"
  done
  if [ "$#" -eq 2 -o "$#" -gt 2 -a -d "${!num}" ]; then
    echo cp "${tmparray[@]}" "${!num}"
  else
    echo "error"
  fi
}

테스트 후 삭제하세요 echo.

이번에는 매개변수가 예상되며 해당 매개변수의 실제 이름이 결정되고 cp단일 매개변수 대신 매개변수 배열을 사용하여 호출이 이루어집니다. 배열에는 단일 매개변수가 포함될 수도 있습니다. cp파일을 덮어쓰거나 새 파일 이름으로 복사하는 대신 항상 디렉터리에만 복사하는 경우 테스트를 조정할 수 있습니다.

관련 정보