
다음 스크립트를 실행할 때 다음 오류가 발생합니다.
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
누군가 문제를 볼 수 있습니까?
답변1
주요 오류 중 하나는 ls
명령을 사용하려고 하는데 LIST 변수에 'ls' 문자열만 포함되어 있다는 것입니다. 구문 과 함께 명령 대체를 사용할 수 있습니다 $(command)
. 이 경우에는 사용하지 않는 것이 좋습니다. 왜냐하면 쉽게 사용할 수 있는 형식으로 정보를 제공하지 않기 때문입니다. 그것은 거의 항상출력을 구문 분석하는 실수ls
.
이러한 상황에서는 셸 패턴 일치라고도 하는 셸 패턴 일치를 사용해야 합니다.글로빙.
대신 스크립트에서 다음 방법을 제안합니다.
#!/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
명령문은 일치 항목이 파일인지(디렉토리 및 링크에서는 실패함) 확인하고 파일인 경우 복사 시퀀스를 수행합니다. - 시스템 환경 변수는 대문자이므로 변수 이름을 소문자로 변경했습니다. 따라서 원치 않는 이름 충돌을 피할 수 있습니다.
답변2
음, 스크립트에 작은 오류가 있습니다. 네 번째 줄에서는 실행하려고 했습니다.ㅋㅋㅋ따라서 작은따옴표로 묶어서는 안 되며 기호 안에 넣어야 합니다.``. 따라서 스크립트는 다음과 같이 변경됩니다.
LIST=`ls`
위와 같이 스크립트를 업데이트해 보세요.
$(ls)
그러나 전혀 사용하지 않는 것이 좋습니다 . 루프 헤더에서 쉘 글로빙을 선호해야 합니다.
for i in *; do
처럼데이비드 앤더슨 씨변수 값에 대한 따옴표와 함께 사용할 수 있다고 아래에 설명되어 있습니다(" $나 ") 그 뒤에 오는 명령문의 경우 파일 이름의 공백으로 인해 문제가 발생할 수 있습니다. 프로세스 대체와 결합된 find를 사용하면 이를 방지할 수 있습니다.
while read l; do
i=$(basename "$l")
done < <(find . -name '*' -maxdepth 1)
스크립트와 설명이 포함된 자세한 답변은 다음과 같습니다.Mr.Arronical. 앞으로 더 나은 스크립팅을 위해 이 내용을 참고하시기 바랍니다.
답변3
'find' 명령 버전
globs 등을 구문 분석하거나 망칠 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/
이미 존재하는 경우에는 실패합니다.