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*在传递给您的函数之前由 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始终仅复制到目录(而不是覆盖文件或复制到新文件名),您可以调整测试。

相关内容