나는 주어진 이름이나 심볼릭 링크를 가진 파일을 주어진 디렉터리에 복사하는 코드를 작성했습니다.
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
linkcp
2개 이상의 매개변수를 가져오되 처음 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
파일을 덮어쓰거나 새 파일 이름으로 복사하는 대신 항상 디렉터리에만 복사하는 경우 테스트를 조정할 수 있습니다.