所定の位置で動作し、結果を出力

所定の位置で動作し、結果を出力

フォルダで実行されるシェル機能があります(私の場合は、* .eps`ファイルを見つけて空の枠なしでpdfに変換します)。次の関数でこれを抽象化してみましょう。

function do_here() {
    echo $(pwd)
}

ROOT_PATH私はルートパスが与えられたディレクトリとパスを繰り返し、do_here各リーフで作業する賢明な方法を探しています。象徴的な葉があるかもしれませんが、現時点ではこの要件はプラスのようです。

理由は次のとおりです。

  1. ROOT_PATHディレクトリを参照するには、別名を使用してくださいto_path
  2. ランニングcd $to_path
  3. ランニングdo_here
  4. ステップ2に進みます。

手順1でディレクトリパスのリストを取得する方法がわかりません。

答え1

Bashは設定されている**場合、再帰ワイルドカードもサポートします。shopt -s globstar.globをサフィックスとして使用すると、ディレクトリのみがインポートされます/dotglob名前がドットで始まるディレクトリを見逃さないように追加されました。

例えば

#!/bin/bash
shopt -s globstar
shopt -s dotglob
do_here() {
    echo "working in $(pwd)...";
}
# cd ROOT_PATH
for d in **/; do (
    cd "$d"
    do_here
)
done

**シェルの仕組み、つまりディレクトリツリー内のシンボリックリンクにはいくつかの違いがあります。ツリーに他のディレクトリへのリンクが含まれている場合は、少なくともいくつかのバージョンのBashがツリーの範囲外になり、それに従います。 (「記号の葉」がどういう意味なのかよく分からないので、それが問題なのかはわかりません。)

答え2

ディレクトリ内のすべてのファイルを取得するのと同じように、すべてのディレクトリを取得するには、次のものを使用できます。ワイルドカード;その後、ループを使用してfor結果を繰り返し、サブシェル(( commands in subshell ))またはpushd/スタックpopdのディレクトリを起動します。たとえば、

#!/usr/bin/zsh
for directory in **/*(ND/) ; do
  print -r -u2 Working on ${directory}
  (             # do in subshell, so that `cd` doesn't affect
                # the next iteration
    cd -- "${directory}" && \
    do_here     # && : only if `cd` succeeded, do `do_here`
  ) || { 
         print -r -- "${directory} failed" >&2 | \
         logger -p user.err 
       }
done

それを分解しよう

for directory in **/*(ND/) ; do
# ^ ^---+---^    ^  ^ ^^^  
# |     |        |  | ||\ *(/) extended glob: match directories
# |     |        |  | |\- *(N) extended glob: null glob, i.e., don't fail if
# |     |        |  | |                       nothing matches
# |     |        |  | \-- *(D) extended glob: include directories starting with 
# |     |        |  |                         ".", i.e., normally hidden dirs
# |     |        |  \---- * glob operator
# |     |        \------- **/ apply the following globbing recursively
# |     |
# |     \---------------- "loop variable": `directory` gets set to each result, 
# |                       consecutively
# |
# \---------------------- for {variable name} in {list-generating expression} :
#                         for loop

関連情報