A execução de um comando dentro da instrução 'if' e no sucesso executa etapas adicionais

4

Eu estava tentando executar um programa que criaria um diretório com base em um caminho completo fornecido a ele a partir do prompt e, se o diretório já existir, ele retornará um erro (para "o diretório já existe") e perguntará novamente para o nome em uma função recursiva.

Aqui está o que eu tentei: digamos um arquivo, test1 :

#!/bin/bash
echo "enter the directory name"
read ab
check(){
if (( echo 'mkdir $ab' 2>/dev/null )); then
  echo "directory created "
  echo 'ls -ld $ab'
  exit
else
  echo "try again "
  echo "enter new value for directory:"
  read ab
  check
fi
}
check

O problema aqui é se o diretório existe, então o programa funciona bem, mas se ele não existir, ele o cria, mas depois vai para a parte else do programa.

    
por AshwaraS 25.12.2014 / 20:53

4 respostas

2

O eco sempre é bem-sucedido. Faça sem ele e o subshell:

#!/bin/bash
echo "enter the directory name"
read ab
check(){
    if mkdir "$ab" 2>/dev/null; then
      echo "directory created "
      ls -ld "$ab"
      exit
    else
      echo "try again "
      echo "enter new value for directory: "
      read ab
      check
    fi
}
check
    
por 25.12.2014 / 21:03
2
(( echo 'mkdir $ab' 2>/dev/null ))
bash: ((: echo  2>/dev/null : syntax error in expression (error token is "2>/dev/null ")

Parênteses duplos envolvem expressões aritméticas . Esse comando que não faz nada perto do que você pretendia. mkdir $ab não escreve nada na saída padrão, então 'mkdir $ab' é uma string vazia, então o conteúdo da expressão aritmética é echo 2>/dev/null . O sinal > é o operador "maior que" aqui e echo é um nome de variável. A expressão aritmética é sintaticamente incorreta (você não pode ter uma variável seguida por um inteiro literal). Como o comando está sintaticamente incorreto, ele retorna um status de erro e a ramificação else é obtida.

Para testar o status de retorno de um comando, basta escrever esse comando.

if mkdir -- "$ab" 2>/dev/null

Dicas adicionais:

  • É uma má ideia esconder os erros de um comando. O usuário precisa saber se o erro é permissão negada, erro de E / S, etc. Para criar um diretório se ele não estiver lá e ser bem-sucedido se o diretório já existir, use mkdir -p -- "$ab" .
  • Sempre use aspas duplas em torno da variável substituições .
  • Se o valor de ab começar com um traço, ele será interpretado como uma opção. Coloque -- primeiro para marcar o final das opções.
por 26.12.2014 / 01:35
1
tries=0
while [ "$((tries+=1))" -le 5 ]    || ! break
      printf 'enter dirname: > '
      IFS=   read -r dir    && 
      if   ! mkdir -- "$dir"
      then   echo try again
      else ! echo Success\!
      fi  
do :; done

Não sei por que você quer negar os status de saída desse tipo, mas acho que o acima deve ter algo parecido com a inversão que você está procurando - e deve ser encerrado após um número limitado de $tries .

Se eu executar ...?

enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again
enter dirname: > .
mkdir: cannot create directory ‘.’: File exists
try again

E ... novamente ...

enter dirname: > doesntexist
Success!
    
por 25.12.2014 / 22:14
0

Essa ideia vai tornar as coisas um pouco mais complexas, mas eu proponho que a maneira mais apropriada de fazer isso é utilizar testes apropriados em seu script. Algo para o efeito de:

#!/bin/bash
if [[ -n $1 ]]; then
  dirname=$1
fi

if [[ -z $dirname ]]; then
  echo "Enter directory name."
  read dirname
fi

check() {
  if [[ -d "$dirname" ]]; then
    echo "Directory already exists."
    echo "Enter new directory name."
    read dirname
    check
  elif [[ -e "$dirname" ]]; then
    echo "$dirname already exists, but is not a directory."
    echo "Enter new directory name."
    read dirname
    check
  else
    if mkdir -p -- "$dirname"; then
      echo "Directory created"
      ls -ld "$dirname"
    fi
    exit
  fi
}
check

Isso preservaria a mensagem de erro da chamada que você faz (mkdir), bem como executaria alguns testes úteis para fornecer feedback sobre o motivo de uma tentativa falhar. Além disso, você pode, opcionalmente, passar o nome do diretório desejado como um argumento de linha de comando, e ele só pedirá que você o insira na segunda tentativa.

    
por 26.12.2014 / 01:57