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
,但这是一个狡辩。
更大的问题是整个功能完全没有意义。
绝对有永远没有它的用例。
它有什么作用?它:
- 用途一些(但不一定是全部)其论点,
- 是否进行文件全局扩展和分词(您可能不知道),
- 将它们作为命令运行,并且
- 打印一条消息,该消息是可能是一个谎言如果命令成功,并且
- 如果命令失败,则打印完全无信息的消息“失败”。
这些都不是有用的功能。
该脚本可以缩短为:
mkdir -p ~/TestFolder
cp -vpR mydata ~/TestFolder/TestFile
这仍然有其自身的奇怪之处,其中之一是从基于主目录的路径 ( ~/TestFolder
) 到基于根目录的路径 ( /TestFolder
) 的转换,但我已经解决了这个问题。一个更奇怪的选择是TestFile
一个名字目录。
但除了这些方面之外,请注意-v
执行复制命令的开关冗长。
另请注意,通过复制整个包含目录,而不是全局扩展,隐藏文件(也称为“点文件”)将被复制,无论 shell 的“dotglob”选项的当前设置如何。
正确编写的 shell 脚本是非常简洁,并且非常强大的。不要重新发明轮子。在添加包装器函数之前,请了解您正在使用的命令的功能。
请阅读伍利奇狂欢指南如果您打算进行任何认真的脚本编写。