bash - UNIX 如何让我的脚本删除多个文件和通配符?
问题描述
我的任务是制作一个模仿 rm 命令的删除脚本。如您所知,如果您要键入类似rm file1 file2
. 使用这个例子,我的脚本只会删除 file2。谁能帮助我如何制作它,以便我的删除脚本会删除所有列出的文件?我的脚本如下。如果它有点混乱,我很抱歉,我是编码新手。
#!/bin/bash
function directory(){
#Checks if deleted directory & .restore.info file exists
#If they don't exist, it creates them
if [ ! -d ~/deleted ]
then
mkdir ~/deleted
fi
if [ ! -f ~/.restore.info ]
then
touch ~/.restore.info
fi
}
function movefile(){
#not currently using
mv "$1" ~/deleted/$1
echo "file moved to recycle bin"
}
function error_conditions(){
#not currently using
#Prints error messages and checks if file is in project directory
if [ ! -f ~/project ]
then
echo "cannot remove $filename: no such file or directory"
elif [ -d ~/project ]
then
echo "cannot remove $filename: is a directory"
else
echo "missing operand"
fi
}
function delete_file(){
#Gets inode for filename
#Takes user input and puts file wherever based on user input
inode=$(stat -c%i "$filename")
pwd=$(readlink -e $filename)
if "$interactive"
then
if [ "$verbose" = true ]; then
read -p "Are you sure you want to delete $filename? " user_input
if [ $user_input == "y" ] || [ $user_input == "Y" ] || [ $user_input == "yes" ] || [ $user_input == "Yes" ];
then
mv $filename ~/deleted/${filename}_$inode
#moves deleted file to deleted directory (with inode at end)
echo ${filename}_$inode:$pwd>>~/.restore.info
#stores info of removed file in .restore.info (with path)
echo "removed '$filename'"
else
echo "Nothing has been deleted"
fi
else
read -p "Are you sure you want to delete $filename? " user_input
if [ $user_input == "y" ] || [ $user_input == "Y" ] || [ $user_input == "yes" ] || [ $user_input == "Yes"];
then
mv "$filename" ~/deleted/${filename}_$inode
echo ${filename}_$inode:$pwd>>~/.restore.info
else
echo "Aborted"
fi
fi
elif "$verbose"
then
mv "$filename" ~/deleted/${filename}_$inode
echo ${filename}_$inode:$inode:pwd>>~/.restore.info
echo "removed '$filename'"
else
mv "$filename" ~/deleted/${filename}_$inode
echo ${filename}_$inode:$pwd>>~/.restore.info
echo "Executed"
fi
}
#Setting all flags to false
interactive=false
verbose=false
recursive=false
while getopts :ivr optionvar
do
case "$optionvar" in
i) interactive=true;;
v) verbose=true;;
r) recursive=true;;
esac
done
shift $((OPTIND-1)) #process arguments.
#doing error commands with help of recursive
for i in $*
do
filename=$i
basefile=$(basename $i)
if [ "$filename" == " " ];
then
echo "No filename provcided"
elif [ -d $filename ];
then
if [ ! $recursive = true ];
then
echo "Directory name provided, please provide a file"
fi
elif [ ! -f $filename ];
then
echo "File does not exist"
# elif [ "$basefile" == "safe_rm" ]
# then
# echo "Attempting to delete safe_rm"
fi
done
#################################M A I N###############################
directory
delete_file $*
#error_conditions $* #- this gives me duplicate output lines
#movefile "$@" - this gives me an unnecessary "mv: cannot stat" output line
解决方案
我不打算对您的整个脚本进行详细的代码审查,但这里有一些注意事项。
- 您正在循环脚本主要部分中的参数,但随后您正在使用多个参数调用删除函数。该函数没有循环。将循环从
main()
to移动delete_files()
(请注意,为了清楚起见,我将其名称复数)。 - 说到
main()
,您不妨将该代码(选项处理、函数调度等)封装在该名称的函数中,然后在脚本的底部有一行调用它:main "$@"
$*
除非您需要它的作用并了解它的用途,否则不要使用 - 而是"$@"
几乎总是使用并总是引用它(极少数例外)- 一致地使用缩进
- 如果您的脚本不需要移植到 Bash 以外的 shell,则使用 Bash 特定的功能,例如
[[ ]]
代替[ ]
- 您同时使用了两种命名函数的方法 (
function f()
)。使用其中一个 - 括号优于使用function
- 所以f () { ...; }
- 使用更多的引号,一些例子:
pwd=$(readlink -e "$filename")
mv "$filename" ~/deleted/"${filename}_$inode"
echo "${filename}_$inode:$pwd" >> ~/.restore.info
- 但我不建议
~
在脚本中使用波浪号 ( ) -$HOME
改为使用。如果您需要查找用户的主目录,请使用getent
而不是其他方法。
推荐阅读
- python - 使用 python 构建 Maven 模块
- asp.net-core - 更改 appsettings.json 中的默认文档
- javascript - 点击 jquery/css 替换单个图像
- ios - iOS13 App黑屏,self.window不工作
- sql - 从 Unix 中的 SQL Server DMZMGMT SQL Server 数据库中获取 TimeValue,然后向用户发送有关经过时间的电子邮件
- c# - MathNet.Numerics 库是否支持 SIMD?
- matlab - 如何计算 (hh:mm:ss + minutes()) 并在 MATLAB GUI 表中显示所有结果?
- react-native - 如何在不使用数据状态的情况下使用 FlatList
- react-native - React-Native 使用 Jest 测试 AppState
- android - 有没有办法使用 Firebase App Distribution 为每个 Android 构建变体配置单独的 serviceCredentialsFile?