cp erro no script

4

Eu recebo o seguinte erro quando executo o script a seguir:

cp: cannot stat ls

Conteúdo do script

#!/bin/bash
#make copies of all files in directory
cd /home/don
LIST='ls'
for i in $LIST; do
    ORIG=$i
    DEST=$i.old
    cp $ORIG $DEST
    echo "Copied $i"
done

Alguém pode ver o problema?

    
por Don 31.08.2016 / 17:30

3 respostas

2

Bem, há um pequeno erro no seu script. Na quarta linha você pretendia executar ls para que ele não ficasse entre aspas simples, mas deveria estar dentro do símbolo '' . Então, seu script muda da seguinte forma

LIST='ls'

Tente atualizar seu script como acima.

No entanto, é aconselhável não usar $(ls) , você deve preferir o shell globbing no cabeçalho do loop.

for i in *; do

Como Mr.David Andersson comentou abaixo que isso poderia ser usado com aspas para valores de variáveis (< strong> "$ i" ) para as instruções seguintes, caso contrário, poderia causar problemas com espaços em nomes de arquivos. Você pode evitar isso usando find combinado com a substituição do processo:

while read l; do
    i=$(basename "$l")
done < <(find . -name '*' -maxdepth 1)

Uma resposta detalhada com script e explicação é dada abaixo por Mr.Arronical . Por favor, consulte-o para um melhor roteiro no futuro.

    
por SAGAR BHOOSHAN 31.08.2016 / 17:36
9

Um dos principais erros é que você está tentando usar o comando ls , mas a variável LIST contém apenas a string 'ls'. Você pode usar a substituição de comando com a sintaxe $(command) . Eu recomendaria contra isso neste caso, como não vai dar-lhe informações no formato que você pode usar facilmente. É quase sempre um erro de analisar a saída de ls .

Nessa circunstância, você deve usar a correspondência de padrões de shell, também conhecida como globbing .

Sugiro o seguinte método no seu script:

#!/bin/bash
#make copies of all files in directory
for i in /home/don/* ; do
  if [[ -f $i ]]; then
    orig="$i"
    dest="${i}.old"
    cp "$orig" "$dest"
    echo "Copied $i"
  else
    echo "${i} is not a file"
  fi 
done
  • Isso usa a globalização do shell para corresponder a todos os arquivos no diretório. %código% significa tudo no diretório atual ( ./* ).
  • A instrução . verifica se a correspondência é um arquivo (haverá falha diretórios e links), e sua sequência de cópias, se for.
  • eu mudei os nomes das variáveis para serem minúsculas, como sistema variáveis de ambiente são maiúsculas, então você evitará qualquer nome indesejado confrontos.
por Arronical 31.08.2016 / 17:36
2

A vesion do comando 'find'

Seu script pode ser feito como um comando find de uma linha, sem a necessidade de analisar ls ou mexer com globs, etc.

Seu objetivo, no que diz respeito à pergunta, é fazer cópias de todos os arquivos no diretório atual. Para isso, o comando apropriado seria:

find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;

O que isto faz é que find opera em todos os arquivos no diretório . (atual) e chama cp por cada arquivo (daí \; ). Como find é recursivo, precisamos limitar a profundidade da pesquisa, portanto -maxdepth flag e -mindepth flag é evitar listar . como um dos resultados da pesquisa.

Execução da amostra:

$ touch "file one"  "file two"                                                 
$ find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;                       
$ ls -1                                                                        
file one
file one.old
file two
file two.old
$ 

OBSERVAÇÃO : cp ainda reclamará dos diretórios. Há algumas maneiras de lidar com isso.

1) você pode filtrar somente arquivos se esse for seu objetivo com -type f sinalizador em find like

find . -mindepth 1 -maxdepth 1 -type f -exec cp {} {}".old" \;

2) Use cp -r para fazer cópias de diretórios também

find . -mindepth 1 -maxdepth 1 -exec cp -r {} {}".old" \;

Python one-liner

Isso é um pouco mais demorado do que find one, mas ainda faz o trabalho e não tem nenhum problema com nomes de arquivos especiais.

python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") for f in os.listdir(".") if os.path.isfile("./" + f)]'

Execução da amostra:

$ touch "test file 1" "testfile 2"
$ python -c 'import shutil;import os;[shutil.copyfile(f,f + ".old")
> for f in os.listdir(".")
> if os.path.isfile("./" + f)]'
$ ls -1  
test file 1
test file 1.old
testfile 2
testfile 2.old
$ 

Para incluir diretórios, use shutil.copytree(source,destination)

python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") if os.path.isfile("./" + f) else shutil.copytree(f,f + ".old") for f in os.listdir(".")]'

Observe que isso falhará se o directory_one.old/ já existir

    
por Sergiy Kolodyazhnyy 07.09.2016 / 10:55