2016-08-14 52 views
4

ls -R pathを使用して実行できることはわかっています。しかし、私はシェル言語の構文や制御構造を学ぶためにしようとしているので、私は自分のコードを記述しようとしている:私はコマンド./ej2.sh ~/Documents/を呼び出すとBashで指定されたディレクトリのファイルを再帰的にリスト表示する

#!/bin/sh 

arg=$1; 

lsRec() { 
    for x in $1*; do 
     if [ -d "$x" ]; then 
      lsRec $x; 
     else 
      echo "$x"; 
     fi 
    done 
} 

lsRec $arg; 

、端末はスロー:segmentation fault (core dumped)を。なぜ私はこのエラーに遭遇していますか?私のコードで何かが見つからないのですか?

ありがとうございました。

+2

あなたはにコードを変更する必要がありますが、質問 'bash'をタグ付けしましたが、あなたのシェバングラインターゲットは' sh'、あなたは(のみ) 'SHを使用しています'-compatible syntax。 – mklement0

+2

もう1つの脇にある:同じ行に_multiple_文を置いたときに文を終了させるには ';'だけが必要です(ただし、 'do'と' 'then'doは同じ行に置かれれば'; 'が必要です)。 – mklement0

答えて

8

lsRec関数は暗黙のうちに引数が "/"で終わると期待しているため、アルゴリズムは無限ループに入ります。最初のレベルは、 "/"で終わるパスを入力として渡しますが、2番目のレベルは再帰呼び出しを行っているパスが "/"で終わらないため動作しません。あなたは再帰呼び出しを行うときにスラッシュを追加するか、lsRec $x/のようになります。あるいは、ループの引数のスラッシュをfor x in $1/*; doのように追加するのが一般的です(システムは一般に隣接する複数のパス区切りを無視します)。今後

、私はパスが空白文字が含まれている場合に問題を回避するための値(例えばfor x in "$1/"*lsRec "$x"lsRec "$arg")を引用するあなたをお勧めします。スキャンしているディレクトリ階層の下に、名前にスペースを含むディレクトリを作成すると、そこに移動します。

4

ここでの問題は、 "for x 1 $ *"が$ 1を見つけたことです。したがって、無限ループになります。

  • チェック$ 1引数に置き換えられているためにループのための "xの$ 1/*"

に渡されたのx == $ 1

  • 変更した場合: 2つの解決方法があります機能は正しい?だから、 "hello"を送ると、 "hello *のxのために"なります。 これはグロブニングパターンであり、 "hello"と無限ループを選択します。

    "hello"が "hello *"ではなく "hello/*"になるため、2番目の解決策が動作します。

    このコードは私のために正常に動作します:

    #!/bin/sh 
    
    arg=$1; 
    
    lsRec() { 
        for x in "$1"/*; do 
         echo "$x" 
         if [ -d "$x" ]; then 
          echo "This is a directory:" 
          lsRec "$x"; 
         else 
          echo "This is not a directory:" 
          echo "$x"; 
         fi 
        done 
    } 
    
    lsRec "$arg"; 
    

    はそれが役に立てば幸い!

  • +3

    スラッシュはまだありませんか? :) –

    +1

    @ mike.dldああはい。今修正されました。ありがとうm8! – tyrerexus

    +1

    @ mklement0今すぐどうぞ。 – tyrerexus

    2

    私はあなたがフォーク爆弾を作成したと思います。あなたのコードは無限再帰を作成します。余談として

    #!/bin/sh 
        arg=$1; 
    
        lsRec() { 
         for x in $1/*; do 
         if [ -d "$x" ]; then 
          echo "$x" ## here you print the line 
          lsRec $x; ## here you pass the contents and NOT the line itself 
             ## your programm was passing dirs without processing 
             ## over and over 
         else 
          echo "$x"; 
         fi 
        done 
    } 
    
    lsRec $arg; 
    
    +1

    訂正ありがとう –

    関連する問題