安装命令复制整个目录的问题

nat*_*wek 23 shell directory utilities coreutils file-copy

所以我有一个包含我的一些配置文件的 repo,我正在尝试创建一个makefile将它们安装在 homedir 中。我遇到的问题是,当我直接在 bash 中运行以下命令时

install -m 755 -d ~/path/to/dotfilesDir/ ~/
Run Code Online (Sandbox Code Playgroud)

似乎什么也没有发生

install -m 755 ~/path/to/dotfilesDir/{file1,file2,...} ~/
Run Code Online (Sandbox Code Playgroud)

按预期工作。

为什么第一个(更简单和更清洁)的解决方案不起作用?

Vra*_*all 12

从@Joseph R. 的回答开始,这是我让它与 find 一起工作的解决方案,因为我无法让他的命令起作用。(我不认为是这样,因为适用于 的规则\+{}元素后不能有任何内容。)(我无法发表评论。这整段实际上可以删除。)

要将所有文件复制到完全相同的目录(此处target/directory):

find directory/to/copy -type f -exec install -Dm 755 "{}" "target/directory" \;
Run Code Online (Sandbox Code Playgroud)

-D 在这里不是强制性的,它只会为目标创建不存在的目录。

要从当前位置开始复制整个目录层次结构及其文件(这将省略空目录):

find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \;
Run Code Online (Sandbox Code Playgroud)

如上所述,这将重新创建从$PWD. 此外,如果您需要复制空目录, on 可以找到使用-type doffind和 的方法install -d

因此,为了复制树,从不是的目录开始$PWD

(cd parent/directory && find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \;)
Run Code Online (Sandbox Code Playgroud)

注意如何parent/directory不被复制。

额外的

对于那些使用shell/fish,这是执行相同操作的行:

fish -c 'cd parent/directory; and find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \\;'
Run Code Online (Sandbox Code Playgroud)


Jos*_* R. 10

手册页看,似乎install不会做你想做的。

事实上,概要部分指出了以下形式的用法:

install [OPTION]... -d DIRECTORY...
Run Code Online (Sandbox Code Playgroud)

后来,手册页说:

-d, --directory
将所有参数视为目录名称;创建指定目录的所有组件

所以在我看来,这个选项的重点是能够安装一个复杂的(但空的)目录结构 à la mkdir -p ...

您可以使用循环完成您想要的操作:

for file in /path/to/DotFiles/dir/*;do
    install -m 755 "$file" ~/
done
Run Code Online (Sandbox Code Playgroud)

或者,如果 下有多个级别/path/to/DotFiles/dir,则可以使用find

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Run Code Online (Sandbox Code Playgroud)

  • `-exec 'install -m 755 "{}" ~/' +` 不起作用,至少在某些(全部?大多数?)版本的 Linux 上不起作用。可能适用于 OSX 或其他东西。如果你想要一个单行代码,使用这样的东西是非常简单的: 1. 递归创建目录: `for d in $(find . -type d); 执行 install -d --mode 755 "$d" "../install-test/$d"; 完成` 2. 递归创建文件:`for f in $(find . -type f); 安装 -D --mode 644 "$f" ../install-test/; 完成` (2认同)