encontrar problema no script bash

0

Estou escrevendo um programa imprimindo o arquivo e o diretório de um diretório especificado. Mas eu tenho que ignorar certo tipo de arquivo. Nós os armazenamos em .ignorefile .

Então, para obter apenas o arquivo que eu quero, eu uso a função find. Mas, eu tenho o mesmo erro toda vez: No such file or directory .

E, quando tento no terminal, funciona perfeitamente com os mesmos argumentos.

Um exemplo:

  • No meu arquivo de ignorar, tenho: *.txt, *.cpp

  • Quando executo meu arquivo .sh , coloco dois argumentos: o arquivo ignorar e um diretório.

  • Então, quando eu digitalizo todo o texto no meu arquivo para construir os arquivos de argumento, eu chamo a minha função store() .

Aqui você pode ver meu código:

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

Aqui a função que constrói 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

Eu chamo de arquivo "sh"

./file.sh -i ignorefile -d Source

saída:

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
    
por Alexis 29.11.2015 / 11:39

2 respostas

2

find_arg é passado como um único argumento (por causa das aspas duplas), o que significa que find está tentando encontrar todos arquivos em um diretório chamado Dir ! -name '*.txt' ! -name '*.cpp' -print (Sim, esse é um nome de diretório válido). Tente printf '%q\n' "$find_arg" para ver os argumentos reais como passados para find . Além disso, se o seu shell suportar matrizes, provavelmente você deve usá-las para armazenar argumentos . E Use More Quotes ™ ! E não use eval aqui - find imprimirá os nomes dos arquivos bem.

    
por 29.11.2015 / 13:12
1
  1. Você diz que seu .ignorefile tem *.txt, *.cpp , mas da saída mostrada, parece que tem \*.txt, \*.cpp . Escapar do * é a origem do seu problema, ele diz find para excluir arquivos com um asterisco literal, em vez de usá-lo como um curinga glob. Então, não faça isso.

  2. Esta versão do seu script corrige algumas falhas e simplifica um pouco. Entre outras coisas, ele separa o processamento de arg (e usa getopts, que é interno para sh) da lógica principal da função backup() .

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"
    
por 29.11.2015 / 21:57