在 Zsh 中,以下操作失败:
$ echo hi > /tmp/this/path/does/not/exist/out.txt
zsh: no such file or directory: /tmp/this/path/does/not/exist/out.txt
显然问题是>
无法创建丢失的父目录。我发现这种行为非常烦人,它应该只创建目录。我怎样才能做到这一点?
cp
使用和 之类的命令mkdir
可以为--parents
选项添加别名。但是>
不能使用别名,因为它不是命令。我能做些什么?
理想情况下,我想在 zsh 中完成此操作,但我会接受“使用不同的 shell”作为答案。
答案1
您始终可以创建:
create() { mkdir -p -- $1:h && cat > $1; }
并使用:
echo something | create path/to/some/file
甚至:
create() {
local dest
for dest do
mkdir -p -- $dest:h || return
done
cat > "$@"
}
为了能够做到:
echo hi | create some/file some/other/file
另一种方法:
makeparents() {
mkdir -p -- $1:h
print -r -- $1
}
和:
echo hi > "$(makeparents path/to/some/file)"
(不适用于以换行符结尾的文件名)
您还可以使用 zsh 的动态命名目录扩展来完成此操作:
redir-parent() {
[[ $1 = n ]] && [[ $2 = p:* ]] || return
local file=${2#p:}
mkdir -p -- $file:h
reply=($file)
}
zsh_directory_name_functions+=(redir-parent)
进而:
echo something > ~[p:path/to/some/file]
path/to/some
作为扩展的一部分将在哪里创建。
无论如何,在所有这些情况下,当创建路径目录组件时,它们将具有受当前 umask 影响的默认权限。
在该cmd | create path/to/file
版本中,cmd
即使/path/to
无法创建或path/to/file
无法打开(并且可能最终被 SIGPIPE 杀死)也会运行。
在其他情况下,失败的重定向将取消cmd
.他们还具有保留cmd
退出状态的优势。
如果无法创建所有目录组件或者无法打开文件进行写入,则最终可能会出现一些即使重定向本身失败,目录也已创建。然后您可能需要进行一些手动清理。