Я получаю следующую ошибку, когда я запускаю скрипт, который следует:
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
Кто-то может видеть проблему?
Ну, в Вашем сценарии существует небольшая ошибка. В четвертой строке Вы означали выполняться 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 . Любезно отошлите его для лучших сценариев в будущем.
Одна из основных ошибок - то, что Вы пытаетесь использовать эти 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
./*
средства все в текущем каталоге (.
). if
оператор проверяет, является ли соответствие файлом (перестанет работать на каталогах и ссылках), и делает Вашу последовательность копии, если это. Ваш сценарий может быть сделан как острота 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" \;
Это немного более длинно это 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/
уже существует