#!/bin/bash
echo "Menu"
echo "1. Backup file"
echo "2. Quit"
echo "Enter Choice"
read Choice
case $Choice" in
1) while :
echo "Enter file name"
read file name
do
if [ -f $filename]
then
current_time=$(date."+%Y.%m.%d")
back_up= "Backup"
new_file=$filename.$back_up.$current_time
echo "New file name is:" "$new_file"
cp $new_file $HOME
else
echo "file does not exists"
fi
done
;;
2) echo "Program Terminated"
exit;;
esac
사용자가 입력한 스크립트 파일을 백업하고 이를 새로운 확장 날짜와 백업으로 홈 디렉토리에 저장하고 파일이 존재하는지 확인하는 쉘 스크립트를 작성해야 합니다. 첫 번째 부분은 제대로 작동하는 것 같지만 다음과 같은 메시지가 나타납니다 cp:cannot stat no file or directory
.
답변1
인용문, 구문, Kali-linux 태그가 여기서는 관련이 없고 Kali는 숙련된 사용자를 위한 것이므로 부적절하다는 사실과 같은 주석은 무시합시다.
#!/bin/bash
echo "Menu"
echo "1. Backup file"
echo "2. Quit"
echo "Enter Choice"
read Choice
따라서 이제 귀하의 옵션은 1
( 2
또는 우리가 무시하고 있는 다른 많은 입력) 중 하나입니다.
case "$Choice" in
1) while :
echo "Enter file name"
read file name
do
2개 변수 file
의 합계를 읽었 name
지만 스크립트의 나머지 부분에서는 두 변수 중 하나를 사용하지 않습니다. 의미하는 바는 다음과 같습니다.
(1) while read -p "Enter file name" filename ; do
if [ -f $filename]
filename
스크립트에서 비어 있으므로 항상 true입니다 . filename
대신 읽으면 file name
결과는 다음과 같습니다.
bash: [: missing `]'
앞에 공백을 삽입해야 합니다 ]
. (인용도 가능)
if [ -f "$filename" ] ; then
current_time=$(date "+%Y.%m.%d")
back_up="Backup"
new_file="$filename.$back_up.$current_time" # quotes
echo "New file name is: $new_file"
cp $new_file $HOME
파일 이름(예: )을 입력하고 있으며 해당 이름이 홈 디렉터리에 foo
복사되고 있습니다 . foo.Backup.2021.03.15
파일이 존재합니까? 아마도 그렇지 않을 것입니다. 메시지를 받았으므로 cp: cannot stat foo.Backup.2021.03.15: No such file or directory
복사하고 싶을 수도 있습니다 foo
.
cp "$filename" "$HOME/$new_file"
cp
파일 이름을 보면 스크립트에서 오류를 찾을 수 있습니다 . Echos는 오류를 찾는 데 좋습니다.
echo "Copying $filename to $HOME/$new_file"
cp "$filename" "$HOME/$new_file"
else
echo "file does not exists"
fi
done
;;
를 사용하여 이 while 루프를 종료해야 합니다 ^D
. 두 번째 Case 문이 루프를 종료할 것이라고 예상하지 않았기를 바랍니다.
2) echo "Program Terminated"
exit;;
esac
도움이 되길 바랍니다.
답변2
우리는 사용자가 스크립트를 실행할 때 실제로 파일을 백업하기를 원한다고 가정합니다. 즉, 대화형 메뉴가 필요하지 않습니다. (또한 선언 시작 부분의 인용 오류에 유의하십시오 case
.)
사용자가 스크립트의 명령줄에 백업하려는 파일의 경로 이름을 전체 경로 이름(탭 완성 기능을 사용할 수도 있지만 스크립트에서는 이를 허용하지 않음) 또는 셸을 통해 입력할 수 있다고 가정합니다. 구성 모드를 통과합니다(스크립트에서도 허용하지 않음). 이는 read
두 번째 대화형 호출과 루프가 스크립트에 제공된 매개변수로 대체될 수 있음을 의미합니다.
그래서 우리는 얻습니다.
#!/bin/bash
if [ "$#" -eq 0 ]; then
cat >&2 <<END_USAGE
This script backs up files and places backups in your
home directory with a timestamp as filename suffix.
Usage:
$0 file [...]
END_USAGE
exit 1
fi
printf -v suffix 'backup.%(%Y.%m.%d)T' -1
for pathname do
if [ ! -f "$pathname" ]; then
printf '"%s" is not found or is not a regular file, ' "$pathname"
printf 'will not back it up\n'
continue
fi >&2
printf -v newname '%s.%s' "${pathname##*/}" "$suffix"
if cp -i "$pathname" "$HOME/$newname"; then
printf 'backed up "%s" as "%s" in your home directory\n' \
"$pathname" "$newname"
else
printf 'failed backing up "%s" as "%s" in your home directory\n' \
"$pathname" "$newname" >&2
fi
done
이렇게 하는 유일한 이유 는 타임스탬프를 얻기 위해 실행하지 않고도 여러 위치에서 사용할 bash
수 있다는 것입니다 ( 4.2 이상에서 작동함).printf -v
date
bash
스크립트를 사용하는 방법과 명령줄 인수 없이 스크립트를 실행할 때 수행되는 작업에 대한 간단한 정보 텍스트를 출력하고 있습니다. 이 정보를 인쇄한 후 스크립트가 종료됩니다.
명령줄 인수( $#
0보다 큼)가 주어지면 반복됩니다.
각 반복마다 주어진 인수가 일반 파일(또는 일반 파일에 대한 심볼릭 링크)로 존재하는지 확인하고, 그렇지 않은 경우 다음 항목으로 이동합니다.
그런 다음 suffix
변수의 기본 이름(이전에 생성됨)과 현재 값을 사용하여 새 파일 이름을 생성합니다 pathname
.
백업 파일이 이미 존재하는 경우를 대비해 실행 중인 복사본을 사용하여 cp -i
사용자에게 파일 덮어쓰기에 대해 "아니요"라고 말할 수 있는 기회를 제공합니다.
시험:
$ ./script script
backed up "script" as "script.backup.2021.03.15" in your home directory
$ ./script scriptantoeh
"scriptantoeh" is not found or is not a regular file will not back it up
$ ./script file{1..3}
"file1" is not found or is not a regular file will not back it up
"file2" is not found or is not a regular file will not back it up
"file3" is not found or is not a regular file will not back it up
$ ./script script
overwrite /home/myself/script.backup.2021.03.15? y
backed up "script" as "script.backup.2021.03.15" in your home directory