長いパスの各サブパスで指定されたコマンドを実行します。

長いパスの各サブパスで指定されたコマンドを実行します。

次のような長い道があるとしましょう。

/a/b/c/d/e/f

コマンドを実行したい。ただパスの各サブパスで:

たとえば、私のコマンドがあれば、cmdこれを行うことができる1行を探しています(おそらく1行ループを使用しています)。

cmd /a
cmd /a/b
cmd /a/b/c
cmd /a/b/c/d
cmd /a/b/c/d/e
cmd /a/b/c/d/e/f

一つこれが必要な理由の1つ(他のタスクにも必要です)は、Unixチームの誰かがcdこのタスクを段階的に実行できるようにしたい/a/b/c/d/e/fからです。chmod g+x回避策があることを確認してください。)避けたいchmod -R g+x /a

私は主にzshで作業していますが、特定のzsh機能を利用できるものがあるかどうか疑問に思います。

答え1

それはまるで

path=/a/b/c/d/e/f
while test "$path" != "/"; do
    chmod g+x "$path"
    path=$(dirname "$path")
done

答え2

入力が速く、すべてのシェルで動作します。

(while [ "$PWD" != / ]; do cmd .; cd ..; done)

角かっこは、ディレクトリの変更をローカルに保持します。あなたの例と同様に、ルートディレクトリは省略されます。cmd実行が失敗した場合に実行を停止するには、開いているset -e;括弧の後に追加します。

答え3

設定ファイルに以下を追加しますzsh

function pathargs {
  local P=$1; local L=${#P}; shift
  local N=1; while [[ $N -le $L ]]; do
    [[ ($N == 1 && ${P[1]} = '/') || \
       ${P[$N]} != '/' && ($N == $L || ${P[$N+1]} == '/') ]] \
    && $@ ${P:0:$N}
    N=$(($N+1))
  done
}

例:

% pathargs /abc/def/ghi/jkl echo
/
/abc
/abc/def
/abc/def/ghi
/abc/def/ghi/jkl

chmod -R g+x代わりにこれを使用できますecho。コマンドは最上位ディレクトリから最初に呼び出されます。

答え4

どうですか?find start_directory -type d -exec my_cmd {} \;

  • /aあなたの例では、start_directory
  • type dディレクトリのみを示します。type fファイル用。このパラメータはファイルとディレクトリ用に予約されています。
  • cmdあなたの例では my_cmd
  • {}見つかったディレクトリ名に置き換える
  • \;忘れないでください。このコマンドがないと、コマンドは実行されません。

実施例1:/homeの下のすべてのフルパスディレクトリ名が印刷されます。

find /home -type d -exec echo {} \;

実施例2A:これはあなたのユースケースです:

find /a -type d -exec echo chmod g+x {} \;

コマンドを印刷しますが、実行しません。実際に必要なものかどうかを確認でき、そうであればbash(または必要に応じてzsh)にパイプすることができます。

find /a -type d -exec echo chmod g+x {} \; | bash

関連情報