在脚本中,如果我将#!/bin/bash放在顶部,这将运行得很好:
cp directory/{foo,bar} destination
但是,对于sh,这将导致错误“没有这样的文件或目录”。在sh中,是否有另一种方法可以用一个命令来完成相同的目标?
发布于 2020-01-27 15:53:22
正如您所观察到的,并非所有的shell都支持支撑展开。
如果您的目标实际上只是在一个命令中这样做,那么一个简单的方法是:
cp directory/file1 directory/file2 destinationcp命令支持多个源参数,后面跟着一个目标参数。实际上,这就是在Bash中为您工作的命令所发生的情况。Bash执行大括号扩展,它将您一直使用的命令转换为上面所示的命令。也就是说,当您在Bash中运行cp directory/{file1,file2} destination时,cp命令永远不会看到任何大括号。
这样的命令简单易懂。我建议你考虑一下。
的变量
但是,如果您的目标是避免重复自己,那么您可能不喜欢这样做,特别是如果directory实际上是一条很长的路。毕竟,如果必须在脚本的后面编辑路径,则必须对这两种情况进行更改。
您可以将directory (或任何可能更长的路径)存储在壳变量中:
dir='directory'
cp "$dir/file1" "$dir/file2" destination$dir是参数展开。shell用变量dir中的值替换它。在使用参数展开时,可以使用不应漏掉 双引号--您希望执行场分裂和球状的除了罕见的情况。(这也适用于Bash。)
这是两个命令,但是如果你的实际目标是避免重复自己,那可能就是你想要的。你可以写
dir='directory'; cp "$dir/file1" "$dir/file2" destination使之成为“一个命令”,但它并不短,而且可读性也有点差。
(请注意,您不能简单地删除那里的;。这样做的结果将是一个良好的命令,但它不会做你想做的事。它将运行cp命令,将一个名为dir的环境变量和值directory传递到cp命令的环境中。因为展开dir的是shell而不是D29命令,所以这是行不通的。)
cdig到前缀如果您的脚本在执行此操作后没有执行任何其他操作,或者对于后续命令来说当前目录是什么并不重要,那么如果destination是一个绝对路径,则可以使用:
cd directory
cp file1 file2 destination但是,我不建议编写脚本,除非您的脚本执行后续操作,这些操作可以从该目录中运行,或者在从该目录运行时可以更简洁或简单地编写。除非脚本从哪个目录运行对脚本的目的是有意义的,依赖它会使脚本更难推理;此外,如果cd命令成功,但cp命令失败,则产生的错误消息可能不完全说明问题。相反,我提到了对源目录使用cding的技术,因为它是交互式shell使用的有用模式。
(作为汉努指出,您可以通过将任意数量的命令封装在一起()在亚壳中运行它们,并且在命令运行后,对C41环境的更改(包括cd的效果)不会持续。这是一种非常有用的技术,我没有提过,这是一个重大的遗漏。但是,请注意,这并没有减轻与相对路径 for destination相关的任何问题。)
注意,如果cd命令失败,其他命令通常仍将运行。这可以复制您不希望复制的不同文件(如果脚本运行的目录中有其他名称相同的文件)或产生令人困惑的错误消息。所以你可能更喜欢:
cd directory && cp file1 file2 destination&&将导致第二个命令运行只有当第一个命令成功时。请注意,这仍然不能撤消运行第一个命令的效果。在运行完整个程序之后,您仍将处于directory中,除非您在带有( )的子still中运行它。
https://askubuntu.com/questions/1206121
复制相似问题