Nomes de arquivos com espaços em scripts

0

Aqui está um script simples para passar um caminho de arquivo para ls ou chmod , mas nomes de arquivos com espaços não funcionam mesmo quando colocados entre aspas.

Como faço para que funcione?

#!/bin/sh
# Script to fix permissions on supplied folder and file name

echo "Enter Folder name"
read folder
echo "Folder name is "$folder
echo "Enter File name - if name includes spaces enclose in single quote marks"
read filename 

echo "File name is "$filename
fullpath="/home/abc/"$folder"/"$filename

echo "Full path is "$fullpath

fixcommand="chmod a+rw -v "$fullpath

echo "Command to be executed is "$fixcommand

echo -n "Is that correct (y/n)? "
read answer
if echo "$answer" | grep -iq "^y" ;then
$fixcommand
else
    echo No action taken
fi 
    
por Chris W 06.03.2018 / 15:11

3 respostas

7

No script fornecido por você, as variáveis não são citadas .

Você deve atualizar seu script e citar as variáveis com ""

Por exemplo:

fullpath="/home/abc/"$folder"/"$filename

Deve ser:

fullpath="/home/abc/$folder/$filename"
% bl0ck_qu0te%

Você pode encontrar abaixo o feedback completo do site de verificação de shell em seu script

Line 5:
read folder
^-- SC2162: read without -r will mangle backslashes.

Line 6:
echo "Folder name is "$folder
                      ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 8:
read filename
^-- SC2162: read without -r will mangle backslashes.

Line 10:
echo "File name is "$filename
                    ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 11:
fullpath="/home/abc/"$folder"/"$filename
                     ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.

Line 13:
echo "Full path is "$fullpath
                    ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 17:
echo "Command to be executed is "$fixcommand
                                 ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 19:
echo -n "Is that correct (y/n)? "
     ^-- SC2039: In POSIX sh, echo flags are undefined.

Line 20:
read answer
^-- SC2162: read without -r will mangle backslashes.
    
por Yaron 06.03.2018 / 15:15
0

As cotações não significam nada para read e aparecerão na variável. As cotas dentro de uma variável também são apenas caracteres regulares: não há nenhuma etapa no processamento do shell em que as cotações entrariam em efeito depois que uma variável fosse expandida.

A única exceção é se você incluir explicitamente outra camada de processamento de shell, executando algo como bash -c "$somevar" ou usando eval . Isso não é uma boa ideia, já que normalmente você iria querer evitar misturar dados e código.

Então, o que você precisa fazer é 1) ter read passar a entrada do usuário para a variável com o mínimo de alterações possíveis e, em seguida, 2) usar a variável entre aspas para passá-la do shell para o comando sem alterações.

read filename por si só é ok, ele manipula os espaços em branco no meio da string. Mas ele remove espaços em branco iniciais e finais e trata as barras invertidas como caracteres especiais. Para desativar esses recursos, use IFS= read -r filename .

Ao usar a variável, você deve executar o comando como chmod a+rw -v "$filename" .

Você não pode salvar a coisa toda em uma variável, não será possível dividi-la corretamente. "$fixcommand" tratará o valor inteiro como uma única string, o nome do comando. $fixcommand irá dividir seu nome de arquivo também. ( BashFAQ 050 discute salvar um comando em uma variável)

Ao todo:

IFS= read -r filename 
fullpath="/home/abc/$folder/$filename"
echo "Command to be executed is: chmod a+rw -v \"$filename\""
# confirmation...
chmod a+rw -v "$filename"
    
por ilkkachu 06.03.2018 / 19:56
-1

Obrigado a todos. Versão final de trabalho:

#!/bin/sh
# Script to fix permissions on supplied folder and file name                  
# including folders and filenames containing spaces
echo "Fixfilepermissions running" 

echo "Enter Folder name"
IFS= read -r folder
echo "Folder name is "$folder
echo "Enter File name"
IFS= read -r filename 
echo "File name is "$filename

fullpath="/home/abc/$folder/$filename"

echo "Full path is "$fullpath

echo "Command to be executed is: chmod a+rw -v \"$fullpath\""
echo -n "Is that correct (y/n)? "
read answer
if echo "$answer" | grep -iq "^y" ;then
chmod a+rw -v "$fullpath"
else
    echo "No action taken"
fi
    
por Chris W 08.03.2018 / 11:05