Como você suspeitava, ele tinha algo a ver com a sintaxe, mas eu também encontrei alguns outros problemas, e surgiu uma versão que simplesmente descartou o uso de xargs em favor de um for loop:
#!/bin/bash
U3=/home/user3/
NF1=/home/user3/mynewfile
File=(grades mynewfile mynewfile1 mynewfile2)
mkdir -p /home/user3/{CIT/{tests,grades},MyStuff/{Tests,Labs},NOS};
echo /etc/hosts.allow > $NF1;
for i in "${File[@]}"; do
cp $NF1 $U3/$i
done
cp $NF1 $U3/CIT/grades/${File[2]}
-
mkdirlinha foi simplificada para descartar as barras finais desnecessárias,mkdirainda cria diretórios com barra final ou não, portanto não há necessidade de mais digitação
As razões para o restante das alterações:
Barra redundante
Em primeiro lugar, ao testar algumas linhas do código original:
$ U3=/home/user3/
$ File=(grades mynewfile mynewfile1 mynewfile2)
$ echo $U3/CIT/grades/${File[2]}
/home/user3//CIT/grades/mynewfile1
O caminho salvo em $U3 foi definido com uma barra final, então a linha $U3/CIT/grades/${File[2]} também possui uma barra após $U3 , fazendo com que o bash a expanda para /home/user3//CIT/grades/mynewfile1 , isso é um problema porque% de barra dupla// não é o mesmo que / , cp por exemplo pode reclamar no such file or directory .
Portanto, se você quis dizer uma barra simples / , o método recomendado é definir apenas $U3 para não ter nenhuma barra final:
$ U3=/home/user3
$ File=(grades mynewfile mynewfile1 mynewfile2)
$ echo $U3/CIT/tests/${File[2]}
/home/user3/CIT/tests/mynewfile1
Portanto, isso agora resulta em um caminho adequado, sem barras redundantes.
Expansão de chave incorreta
Com isso corrigido, o próximo bug foi:
$ echo $U3/CIT/tests/${File[*]}
/home/user3/CIT/tests/grades mynewfile mynewfile1 mynewfile2
Suponho que você pretendia expandir os nomes dos arquivos na matriz File , usando /home/user3/CIT/tests como um prefixo comum, como essa expansão de chave com vírgulas:
$ echo tweedle{dum,dee}
tweedledum tweedledee
Nesta forma de expansão de chave
- uma string fica bem ao lado da chave
{antes ou depois de}ou de ambos, o que você fez corretamente - mas uma
word, comma,outra palavra é usada, etc - no entanto, você coloca um
${File[*]}, eu ainda não vi funcionar com o conteúdo da matriz dessa maneira
Em vez disso, para produzir uma lista feita combinando a mesma palavra ou string inicial comum ( $U3 ) mais outra parte que seja diferente baseada em uma matriz ( $File ), eu recomendo um for loop:
$ for i in "${File[@]}"; do
> echo $U3/$i
> done
Observe que você não digita > , bash automaticamente fornece isso para indicar continuação de linha. Em um script você acabou de ter:
for i in "${File[@]}"; do
echo $U3/$i
done
O resultado é sempre
/home/user3/grades
/home/user3/mynewfile
/home/user3/mynewfile1
/home/user3/mynewfile2
- em
for i in "${File[@]}"; do, a cotação ("), mais@é importante para ter o loopforentendendo corretamente cada nome de arquivo em$Filearray como argumentos separados.
Teste
Por fim, o objetivo é copiar um único arquivo, referenciado pela variável $NF1 , para vários locais, definidos pela expansão de $U3 plus $File array mais $U3/CIT/tests/${File[2]}
A melhor prática para fazer um teste com echo e o comando que você pretende executar, neste caso cp , para que você possa ver o que será executado, a menos que queira usar set . Então, primeiro para o nosso teste:
$ NF1=/home/user3/mynewfile
Então
$ for i in "${File[@]}"; do
> echo cp $NF1 $U3/$i
> done
cp /home/user3/mynewfile /home/user3/grades
cp /home/user3/mynewfile /home/user3/mynewfile
cp /home/user3/mynewfile /home/user3/mynewfile1
cp /home/user3/mynewfile /home/user3/mynewfile2
Além disso, parece que você deseja copiar para $U3/CIT/grades/${File[2]} , para que não seja esquecido, mas adicione-o como uma linha adicional:
$ echo cp $NF1 $U3/CIT/grades/${File[2]}
cp /home/user3/mynewfile /home/user3/CIT/grades/mynewfile1
- tudo ecoa os comandos
cpque seriam executados - pode ser reescrito para direcionar os argumentos para usar
xargssemelhante ao seu código original, mas isso realmente envolve mais digitação, então evitamos
Portanto, basta remover o echo neste exemplo de texto para criar a versão final do código.