在shell脚本函数中使用cp()不起作用

在shell脚本函数中使用cp()不起作用

mkdir 工作正常,但它不会复制(也不会抛出错误)。

#!/bin/sh

copy_function() {

if $1 $2 $3 $4;then
    echo "copied directory and contents"
else
    echo "failed"
    exit 1
fi
}

copy_function mkdir -p ~/TestFolder/TestFile/
copy_function cp -pr my_data/* /TestFolder/TestFile/

答案1

copy_function() {

if $1 $2 $3 $4;then
    echo "copied directory and contents"
else
    echo "failed"
    exit 1
fi
}

copy_function mkdir -p ~/TestFolder/TestFile/
copy_function cp -pr my_data/* /TestFolder/TestFile/

我们来解构这个函数。它实际上有什么作用?

首先,它需要四个参数;如果给出的参数超过这个数字,它将忽略除前四个之外的所有参数。

以开头的行if表示:

使前四个位置参数(该函数接收的参数)服从于文件全局扩展,然后在空白处进行分词,然后尝试将结果行作为命令运行(第一个单词用作命令,其余部分作为参数传递给该命令)。

更好的方法是使用全部位置参数,以及不是让它们接受额外的文件全局扩展过程和分词,将是:

if "$@"; then

下一行输出一条消息“复制的目录和内容”。这条线的问题在于它具有极端的误导性——那就是不是该函数做了什么。该函数执行收到的第一个参数中表达的任何操作。如果我要跑步copy_function rm -r -f ~,我会实际上正在删除我的主目录,但我会收到输出消息“复制的目录和内容”。所以这条线是一个谎言。

接下来的两行,else至少echo "failed"更准确,因为他们并没有试图说什么失败的。不过,理想情况下,错误输出将传递到标准错误而不是标准输出:

else
    echo failed >&2

exit 1如果您确实希望整个脚本立即退出,则该命令可能适合在脚本中使用。改用它可能会更好return 1,但这是一个狡辩。

更大的问题是整个功能完全没有意义。

绝对有永远没有它的用​​例。

它有什么作用?它:

  1. 用途一些(但不一定是全部)其论点,
  2. 是否进行文件全局扩展和分词(您可能不知道),
  3. 将它们作为命令运行,并且
  4. 打印一条消息,该消息是可能是一个谎言如果命令成功,并且
  5. 如果命令失败,则打印完全无信息的消息“失败”。

这些都不是有用的功能。

该脚本可以缩短为:

mkdir -p ~/TestFolder
cp -vpR mydata ~/TestFolder/TestFile

这仍然有其自身的奇怪之处,其中之一是从基于主目录的路径 ( ~/TestFolder) 到基于根目录的路径 ( /TestFolder) 的转换,但我已经解决了这个问题。一个更奇怪的选择是TestFile一个名字目录。

但除了这些方面之外,请注意-v执行复制命令的开关冗长。

另请注意,通过复制整个包含目录,而不是全局扩展,隐藏文件(也称为“点文件”)将被复制,无论 shell 的“dotglob”选项的当前设置如何。


正确编写的 shell 脚本是非常简洁,并且非常强大的。不要重新发明轮子。在添加包装器函数之前,请了解您正在使用的命令的功能。

请阅读伍利奇狂欢指南如果您打算进行任何认真的脚本编写。

相关内容