Bashスクリプトで問題を見つける

Bashスクリプトで問題を見つける

私は指定されたディレクトリのファイルとディレクトリを印刷するプログラムを書いています。ただし、特定の種類のファイルは無視する必要があります。私たちはそれらを.ignorefile

だからあなたが望むファイルを得るために検索機能を使用します。ただし、毎回同じエラーが発生しますNo such file or directory

また、端末で試してみると、同じパラメータで完全に機能します。

一例:

  • 私の無視ファイルには次のものがあります。*.txt, *.cpp

  • .shファイルを実行するときは、「ファイルを無視」と「ディレクトリを無視」という2つのパラメータを入力します。

  • 次に、ファイル内のすべてのテキストをスキャンしてパラメータファイルを設定するときに関数を呼び出しますstore()

ここで私のコードを見ることができます。

    function store(){
      dir="$1" 
      find_arg="$2" # Dir ! -name '*.txt' ! -name '*.cpp' -print
      echo $find_arg
      cmd=`find "$find_arg"`
      echo $cmd
    }

find_argsを構築する関数は次のとおりです。

function backup()
{
  if [ $1="-i" ] && [ -f $2 ]
  then
    backignore=$2
    if [ $3="-d" ] && [ -d $4 ]
    then
      directory=$4
      find_arg=" $directory"
      while IFS='' read -r line || [[ -n "$line" ]]; do
        find_arg+=" ! -name "
        find_arg+="'"
        find_arg+=$line
        find_arg+="'"
      done < "$backignore"
      find_arg+=" -print"
      store $directory "$find_arg"
    else
      echo "please entrer a right directory"
    fi
  else
    echo "Please enter a right ignore file"
  fi
}

backup $1 $2 $3 $4

私はそれを「sh」ファイルと呼ぶ。

./file.sh -i ignorefile -d Source

出力:

Source ! -name '\*.cpp' ! -name '\*.txt' -print
Source/unix_backup/example_files/backignore   
Source/unix_backup/example_files/Documents/rep1/file3.txt
Source/unix_backup/example_files/Documents/rep1/file4.cpp   
Source/unix_backup/example_files/Documents/rep3 
Source/unix_backup/example_files/Documents/rep3/rep4 
Source/unix_backup/example_files/Documents/rep3/rep4/file7.txt    
Source/unix_backup/example_files/Documents/rep3/rep4/file8.cpp

答え1

find_arg単一引数として渡される(二重引用符のため)これは次のことを意味します。find検索しようとしていますみんなファイルは名前の下にあります。Dir ! -name '*.txt' ! -name '*.cpp' -print(はい、有効なディレクトリ名です。)printf '%q\n' "$find_arg"に渡された実際のパラメータを確認してくださいfind。また、シェルが配列をサポートしている場合は、おそらくパラメータを保存するために使用します。。そしてより多くの引用を使用™evalここでは使用しないでください。findファイル名が正しく印刷されます。

答え2

  1. .ignorefileにこのファイルがあると言いましたが、*.txt, *.cpp表示された出力ではそうです\*.txt, \*.cpp。エスケープは*問題の原因であり、findアスタリスクをグローバルワイルドカードとして使用するのではなく、文字通りアスタリスクのあるファイルを除外するように指示します。だからしないでください。

  2. このバージョンのスクリプトはいくつかのバグを修正し、少し単純化しました。とりわけ、backup()関数の基本ロジックからarg処理(およびshの組み込みgetoptsを使用)を分離します。

function store() {
    echo find "$@"
    find "$@"
}   

function backup() {
  directory="$1"
  backignore="$2"

  # skip comments and blank lines
  sed -e 's/#.*// ; /^[[:space:]]*$/d' "$backignore" |
      while IFS= read -r line ; do
          find_arg+=" ! -name '$line'"
      done 
  find_arg+=" -print"
  store "$directory" $find_arg
} 

usage() { 
    echo "$(basename $0) [ -d directory ] [ -i ignorefile ]"
    exit 1
}   

directory=''
backignore='.ignorefile'    # default

while getopts "i:d:h" opt ; do
  case "$opt" in
    d)  directory="$OPTARG" ;;
    i)  backignore="$OPTARG" ;;
    *) usage ;;
  esac 
done

[ -z "$directory" ] && echo "Please provide a directory." && usage

backup "$directory" "$backignore"

関連情報