Por que meu comando 'rm' funciona bem no terminal no meu mac, mas não no shell script?

0

Eu tenho um diretório cujo nome contém espaços. Eu preciso remover o conteúdo deste diretório específico. Estou escapando de espaços no nome do diretório com \ antes de remover o conteúdo. O comando rm funciona bem no terminal, mas não funciona se eu usá-lo no script Shell. Eu recebo um erro No arquivo ou diretório .

Por exemplo Eu tenho seguindo estrutura de diretórios %código% Eu preciso remover tudo dentro do diretório "dir com espaços". O código nos meus scripts da Shell parece

#!/bin/sh
TEMP_DIR="$HOME/Documents/temp dir/dir with spaces"
TEMP_DIR=$(echo $TEMP_DIR | sed 's/ /\ /g')
COMMAND="rm -r $TEMP_DIR/*"
echo "Command: $COMMAND"
rm -r "$TEMP_DIR"/*

Quando executo este script, obtenho o erro No file or directory enquanto o mesmo comando funciona bem se apenas copiá-lo e executar a partir do terminal.

Saída:

Command: rm -r /Users/Neeraj/Documents/temp\ dir/dir\ with\ spaces/*
rm: /Users/Neeraj/Documents/temp\ dir/dir\ with\ spaces/*: No such file or directory

Qual é a maneira correta de fazer isso?

Nota : estou usando o macOS

    
por Neeraj Damle 31.08.2018 / 10:04

2 respostas

2

A resposta do @Olorins é a resposta correta para essa pergunta, mas quero adicionar mais algumas informações por que ela não funciona:

Você pode usar um destes:

rm "dir with spaces"
rm dir\ with\ spaces
dir="dir with spaces"; rm "$dir"

Mas isso não funciona:

dir="dir\ with\ spaces";
rm "$dir" # the backslash will be taken literally inside quotes 
rm $dir # this should work, shouldn't it? Please read below.

A última opção não foi intuitiva para mim no começo. Mas o bash expande o conteúdo da variável, adicionando algumas citações antes da execução .

Você pode usar set -x para ver o que realmente é executado:

( var="a\ b"; set -x; echo $var; )
+ echo 'a\' b
a\ b

Enquanto a saída parece boa, o espaço ainda está sem escape porque o \ está entre aspas simples.

    
por 31.08.2018 / 10:30
1

Você está usando as duas citações e escapando com barra invertida. Usando apenas citar funcionará bem.

Isso deve ser suficiente:

TEMP_DIR="$HOME/Documents/temp dir/dir with spaces"
COMMAND="rm -r $TEMP_DIR/*"
echo "Command: $COMMAND"
rm -r "$TEMP_DIR"/*

Nesse caso, as barras invertidas e aspas devem ser manipuladas pelo shell, para impedir que ele divida o nome do diretório. Quando você usa ambos, o shell preservou os espaços e as barras invertidas entre aspas, então rm na verdade obtém .../temp\ dir/dir\ with\ spaces/... nos argumentos onde deveria ter .../temp dir/dir with spaces/... .

Quando você copia o comando impresso, o shell vê as barras invertidas sem aspas adicionais, preservando os espaços protegidos pelas barras invertidas e removendo as barras invertidas, portanto, rm obtém .../temp dir/dir with spaces/... nos argumentos.

    
por 31.08.2018 / 10:12