我编写了一些代码,将给定名称或符号链接的文件复制到给定目录。
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*
在传递给您的函数之前由 shell 对其进行扩展,因此您实际运行的是
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
得到两个以上的参数,但只关心前两个。
你需要这样的东西:
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
始终仅复制到目录(而不是覆盖文件或复制到新文件名),您可以调整测试。