O script bash simples não está funcionando

O script bash simples não está funcionando

Este script deve copiar todos os arquivos cujos nomes são fornecidos como argumentos na linha de comando para o diretório inicial do usuário. Se nenhum arquivo tiver sido fornecido, o script deverá usar read para solicitar nomes de arquivos e copiar todos os nomes de arquivos fornecidos na resposta para o diretório inicial do usuário.

if [ -z $1 ]
then
    echo provide filenames
    read $FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

Se eu fornecer argumentos como string - funciona. Mas se eu fornecer como "ler $FILENAMES" - não funciona.

O Mentor mostra a mesma solução em suas aulas, mas não mostra como funciona. insira a descrição da imagem aqui

UPDATE Depois de inserir os nomes dos arquivos como argumentos, ele fornece strings vazias e não copiou os arquivos para o local $HOME

[dmytro@oc1726036122 ~]$ cd Desktop/
[dmytro@oc1726036122 Desktop]$ . totmp 
provide filenames
one two
the following filenames have been provided:
the following filenames have been provided:
[dmytro@oc1726036122 Desktop]$

Responder1

O readdeclara variáveis ​​em vez de lê-las. Simplificando, remova $de reade pronto.

if [ -z $1 ]
then
    echo provide filenames
    read FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

EDIT: Vejo que você usa o comando source( .) para executar um script.

[dmytro@oc1726036122 Desktop]$ . totmp

Pode ser bom para este script específico, mas nunca faça isso para scripts complexos. Caso contrário, você obtém qualquer variável ou função desse script em seu shell. Apenas usebash totmp

Responder2

O problema que parece estar bloqueando você é que o readcomando está incorreto, o argumento passado para ele deve ser um nome de variável e por isso deve ser passado sem um $(o $irá expandir o conteúdo da variável, que estará vazia naquele ponto , então o resultado é readsem nenhum nome de variável passado para ele.)

read FILENAMES

Há outro problema com a verificação da ausência do primeiro argumento da linha de comando. Se não estiver presente, $1será expandido para nada (não para uma string vazia), o que pode causar problemas com o [comando, já [ -z ]que não deveria ser válido, [ -z "" ]é o que você esperaria verificar nesse caso. Resumindo, você precisa citar essa variável:

if [ -z "$1" ]

Como você está usando o bash, você também pode usar [[ ... ]], o que geralmente é melhor, pois é um comando interno (nesse caso, esse comando deve funcionar sem aspas, mas manter as aspas não faz mal e parece bom).

(PS: Há muito mais coisas erradas com este script, está tão longe das melhores práticas, estou realmente chocado ao ver alguém ensinar isso. Infelizmente, parece que o padrão é muito baixo para ensinar bash e os manuais são muito complexos até você realmente entende bem, então também não sei se teria uma recomendação melhor sobre como aprender corretamente.)☹️

Responder3

O readcomando pega a variável, mas você já está se referindo aos valores da variável:

 #correct syntax
 read variable
 #wrong syntax
 read $variable

$variableé o valor de variablee no início do script isso não está definido/vazio.

informação relacionada