使用 shell 重定向时创建父目录

使用 shell 重定向时创建父目录

在 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退出状态的优势。

如果无法创建所有目录组件或者无法打开文件进行写入,则最终可能会出现一些即使重定向本身失败,目录也已创建。然后您可能需要进行一些手动清理。

相关内容