#!/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
たが、スクリプトの残りの部分では2つの変数の1つを使用しません。意味するものは次のとおりです。
(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
。 2番目のCaseステートメントがループを終了すると予想していないことを願っています。
2) echo "Program Terminated"
exit;;
esac
お役に立てば幸いです。
答え2
私たちは、ユーザーがスクリプトを実行するときに実際にファイルをバックアップしたいとします。つまり、インタラクティブメニューは必要ありません。 (また、宣言の最初の引用エラーに注意してくださいcase
。)
ユーザーがスクリプトのコマンドラインにバックアップしたいファイルのパス名をフルパス名(タブ補完機能を使用することもできますが、スクリプトではこれを許可しない)またはシェルを介して入力できるとします。設定モードに合格します(スクリプトでも許可されていません)。これはread
、2番目の対話型呼び出しとループがスクリプトに指定されたパラメータで置き換えられることを意味します。
だから我々は得る。
#!/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