シェルリダイレクトを使用したときに親ディレクトリを作成する

シェルリダイレクトを使用したときに親ディレクトリを作成する

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でこれをやりたいのですが、「他のシェルの使用」を答えとして受け入れます。

答え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場合でも実行されます(最終的にはSIGPIPEによって終了する可能性があります)。/path/topath/to/file

それ以外の場合、失敗したリダイレクトはキャンセルされます。シャットダウン状態を保存できるという利点cmdもあります。cmd

すべてのディレクトリコンポーネントを作成できない場合、またはファイルを書き込むために開くことができない場合は、次の問題が発生する可能性があります。一部リダイレクト自体が失敗してもディレクトリが作成されます。その後、手動でクリーンアップする必要があります。

関連情報