ошибка CP в сценарии

Я получаю следующую ошибку, когда я запускаю скрипт, который следует:

cp: cannot stat ls

Содержание сценария

#!/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

Кто-то может видеть проблему?

4
задан 31 August 2016 в 11:02

3 ответа

Ну, в Вашем сценарии существует небольшая ошибка. В четвертой строке Вы означали выполняться ls, таким образом, это не должно быть в одинарных кавычках скорее, это должно быть перенесено в символе '' . Таким образом, Ваш сценарий изменяется как следующим образом

LIST=`ls`

Попытка, обновляющая Ваш сценарий как выше.

Однако желательно не использовать $(ls) вообще, необходимо предпочесть оболочку globbing в заголовке цикла.

for i in *; do

Так же как г-н David Andersson прокомментировал, ниже которого это могло использоваться с кавычки для значений переменных (" $i", ) для операторов после него еще он мог сделать проблемы с пробелами в именах файлов. Можно предотвратить это при помощи находки, объединенной с заменой процесса:

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

А подробный ответ со сценарием и объяснением дан ниже г-н Arronical . Любезно отошлите его для лучших сценариев в будущем.

2
ответ дан 23 November 2019 в 11:40

Одна из основных ошибок - то, что Вы пытаетесь использовать эти ls команда, но список переменных только содержит строку 'ls'. Можно использовать замену команды с $(command) синтаксис. Я отговорил бы от него в этом случае, поскольку это не собирается давать Вам информацию в формате, который можно легко использовать. Это почти всегда ошибка проанализировать вывод ls .

При этом обстоятельстве необходимо использовать сопоставление с образцом оболочки, также известное как globbing.

я предложил бы следующий метод в Вашем сценарии вместо этого:

#!/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
  • Это использует оболочку globbing для соответствия всем файлам в каталоге. ./* средства все в текущем каталоге (.).
  • if оператор проверяет, является ли соответствие файлом (перестанет работать на каталогах и ссылках), и делает Вашу последовательность копии, если это.
  • я изменил имена переменной, чтобы быть нижним регистром, поскольку системные переменные являются верхним регистром, таким образом, Вы избежите любых нежелательных столкновений имени.
9
ответ дан 23 November 2019 в 11:40

Версия команды 'находки'

Ваш сценарий может быть сделан как острота find команда, без потребности парсинга ls или питание с шариками, и т.д.

Ваша цель, до чтений вопроса, состоит в том, чтобы сделать копии всех файлов в текущем каталоге. Для этого соответствующая команда была бы:

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

То, что это делает, является этим find воздействует на все файлы в . (текущий) каталог и вызовы cp на каждый файл (следовательно \; ). Поскольку find является рекурсивным, это мы должны ограничить глубину поиска, следовательно -maxdepth флаг, и -mindepth флаг должен постараться не перечислять . как один из результатов поиска.

Образец выполняется:

$ 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
$ 

Примечание: cp будет все еще жаловаться на каталоги. Существует несколько способов иметь дело с этим.

1) Вы могли отфильтровать только файлы, если это - Ваша цель с -type f флаг в find как

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

2) Использовать cp -r сделать копии каталогов также

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

Острота Python

Это немного более длинно это find один, но все еще сделали задание и не имеет никакой проблемы со специальными именами файлов.

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

Образец выполняется:

$ 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
$ 

Для включения каталогов использовать 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(".")]'

Обратите внимание, что это перестанет работать, если скажут directory_one.old/ уже существует

2
ответ дан 23 November 2019 в 11:40

Другие вопросы по тегам:

Похожие вопросы: