Linux作业

备份工具

班级: 计算机xxxx   学号: xxxxxxxxxxxxxxx   姓名: xxx

实现一个特殊的备份工具bak(即创建bak.sh)

(1)备份命令格式:bak dir1 dir2

功能:将dir1中的所有文件(含子目录中的文件)备份到dir2目录,且将所有子目录以“-”连接

例如,dir1/a/b/c文件将备份为dir2/a-b-c

(2)恢复命令格式:bak -x dir1 dir2

功能:将dir1中的所有文件恢复到dir2目录,并还原备份前的目录结构

例如,bak -x dir2 dir3,将原备份的文件恢复到一个新的目录dir3

请以附件中dic.tar为例(dic.tar需先解包)进行验证。

附:34.1.4节 字符串操作

img

img

img

代码部分:

#!/bin/bash                                                                         
# 如果参数个数为2一下, 直接退出脚本,                                    
if [ $# -lt 2 ]; then                                          
	exit 1                                   
fi                                                                                
# 定义变量                                        
string=""                                           
current_parent_dir_name="" 
flag=0                       
slash="/"                                 
option="-x"                               
a="-"                                                                        
# 不为还原选项                              
if [ ! $1 = $option ]; then                                
	parent_dir_name=$1                             
	ls -R $1 | while read line; do                                       	
	 # 获取父目录名字                     
	 if [ $flag -eq 0 ]; then                           
	 	flag=1                                    
	 	length=${#line}                          
	 	let length_1=$length-1                              
	 	current_parent_dir_name=${line:0:$length_1}                 
	 else                                            
	 	file_name="$current_parent_dir_name$slash$line"                 
	 	# 如果是普通文件                        
	 	if [ -f $file_name ]; then          
	 		for (( i=0; i<${#current_parent_dir_name}; i++)); do   
	 			char=${current_parent_dir_name:$i:1}     
	 			if [ $char = $slash ]; then                  	
	 				char="-"                             
	 			fi                                        
	 			string=${string}${char}                   
	 		done                                          
	 		# 主目录下面拷贝过去, 直接拷贝                 
	 		if [ $parent_dir_name = $string ]; then      
	 			string="$2$slash$line" 
	 			cp $file_name $string      
	 			# 子目录拷贝过去, 文件名改变                    
	 		else                                          
	 		# 除去主目录的名称               
				string=${string:${#parent_dir_name}+1:${#string}}                               	
				# 目录名-文件名                        
				string="${string}${a}${line}"                      
				# 拷贝目录名 / 拷过去要改的名字              
				string="$2$slash$string"                                
				cp $file_name $string               		
			fi                     
				# 如果是空 ""                                   
			elif [ ${#line} -eq 0 ]; then                    
				flag=0                                                                    
			fi                            
			string=""                              
		fi                              
	done                                  
# 还原选项                           
elif [ $1 = $option ]; then                     
	parent_dir_name=$3                     
	index=0                           
	ls $2 | while read line; do                                         
	for(( i=0; i<${#line}; i++)); do                          
	char=${line:$i:1}      
#            echo "char=$char"                    
		if [ $char = $a ]; then                    
			array[$index]=$string   
#                echo "array[$index]=${array[$index]}"                            
			let index=$index+1                                
			string=""                          
		else                          
			string="$string$char"                          
		fi                                  
	done                            
	array[$index]=$string  
#        echo "array[$index]=${array[$index]}"           
	file_name=${array[$index]}                           
	string=""                     
	for (( i=0; i<$index; i++)); do                      
		let s=$i-1                          
		# 拼接成要还原的目录下的路径           
		if [ $i -eq 0 ]; then                                              
			string=$parent_dir_name$slash${array[$i]}                      
		else
#			echo "前: $string"                                     
            string=$string$slash${array[$i]}
#			echo "后: $string"
		fi          
#            echo "路径:$string"               
		# 目录不存在就创建              
		if [ ! -d $string ]; then 
#                echo "mkdir $string"                          
			mkdir $string                                 
		fi                             
		let j=$i+1                        
		# 当前目录是最后一级目录           
		if [ ! $j -lt $index ]; then                              
			# 除去文件前缀                              
			length=0                               
			for (( i=0; i<$index; i++)); do                       
				if [ $i -eq 0 ]; then                   
					let length=${#array[$i]}+length                     
				else                 
					let length=${#array[$i]}+length                 
					let length=$length+1                      
				fi                                   
			done                    
			let length=$length+1              
			r=${line:$length:${#line}}                                          
			line=$2$slash$line                      
			string=$string$slash$r                    
			echo "cp $line $string"                         
			cp $line $string                                    
		fi                                    
	done                                
	if [ $index -eq 0 ]; then                                         
		line=$2$slash$line
#            echo "cp $line $parent_dir_name$slash" 
		cp $line $parent_dir_name$slash                                        
	fi                                      
	string=""                  
	index=0   
	done
fi

make&makefile

班级: 计算机xxx   学号: xxxxxxxxx   姓名: xxxx

diction是一个经典的Unix小工具,用来检测使用不当的英文短语。请前往 http://www.gnu.org/software/diction/ 下载diction源码包,(下载地址:http://ftp.gnu.org/gnu/diction/,diction-0.7.tar.gz)并完成:

(1) 按以下命令将diction安装到当前目录

./configure --prefix=$PREFIX
make
make install

(其中,PREFIX请先在当前目录创建dic目录,并使用dic目录的绝对路径)

测试diction命令的使用,(测试用例请参考share/diction/C中的短语)

(2) 请简要分析Makefile文件(参考Makefile使用指南 https://makefiletutorial.com/ )

答:

(1)软件安装

#1. 预备阶段
wy@ZeroJean:~/$ which gcc
/usr/bin/gcc
wy@ZeroJean:~/$ which clang
/usr/bin/clang
wy@ZeroJean:~/$ which make
/usr/bin/make
#2. 下载diction源码包,也可以通过访问网站下载上传安装源码包
wy@ZeroJean:~/$ ftp -p ftp.gnu.org
Name (ftp.gnu.org:anno): anonymous
ftp> cd gnu/diction
wy@ZeroJean:~/$ ls
diction-0.7.tar.gz
#3. 解压源码包
wy@ZeroJean:~/$ tar -xvf diction-0.7.tar.gz
diction-0.7/COPYING
diction-0.7/INSTALL
diction-0.7/Makefile.in
diction-0.7/README
diction-0.7/configure
diction-0.7/install-sh
diction-0.7/de
diction-0.7/en
diction-0.7/config.guess
diction-0.7/config.h.in
diction-0.7/config.sub
diction-0.7/configure.in
diction-0.7/diction-en.msg
diction-0.7/diction.1.in
diction-0.7/diction.c
diction-0.7/getopt.c
diction-0.7/getopt.h
diction-0.7/getopt1.c
diction-0.7/misc.c
diction-0.7/misc.h
diction-0.7/sentence-en.msg
diction-0.7/sentence.c
diction-0.7/sentence.h
diction-0.7/style-en.msg
diction-0.7/style.1
diction-0.7/style.c
wy@ZeroJean:~/diction$ ls
diction-0.7  diction-0.7.tar.gz
#4. 检查源码
wy@ZeroJean:~/$ tree diction-0.7
diction-0.7
├── config.guess
├── config.h.in
├── config.sub
├── configure
├── configure.in
├── COPYING
├── de
├── diction.1.in
├── diction.c
├── diction-en.msg
├── en
├── getopt1.c
├── getopt.c
├── getopt.h
├── INSTALL
├── install-sh
├── Makefile.in
├── misc.c
├── misc.h
├── README
├── sentence.c
├── sentence-en.msg
├── sentence.h
├── style.1
├── style.c
└── style-en.msg

0 directories, 26 files
#5. 生成程序 ./configure --prefix=$PREFIX,指定当前目录与目标目录
wy@ZeroJean:~/$cd diction-0.7
wy@ZeroJean:~/diction-0.7$ ./configure --prefix=../diction
loading cache ./config.cache
checking host system type... Invalid configuration `x86_64-pc-linux-gnuoldld': machine `x86_64-pc' not recognized

checking for gcc... gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for a BSD compatible install... /usr/bin/install -c
checking for strerror... yes
checking for broken realloc... no
updating cache ./config.cache
creating ./config.status
creating Makefile			#生成Makefile文件
creating config.h
wy@ZeroJean:~/diction-0.7$ ls -l
total 312
-rw-r--r-- 1 wy wy  1094 Jan 17 12:26 config.cache
-rwxr-xr-x 1 wy wy 20370 Aug 22  1998 config.guess
-rw-r--r-- 1 wy wy   194 Jan 17 12:26 config.h
-rw-r--r-- 1 wy wy   129 Aug 22  1998 config.h.in
-rw-r--r-- 1 wy wy  1674 Jan 17 12:26 config.log
-rwxr-xr-x 1 wy wy  7429 Jan 17 12:26 config.status
-rwxr-xr-x 1 wy wy 19236 Aug 22  1998 config.sub
-rwxr-xr-x 1 wy wy 41741 Aug 22  1998 configure
-rw-r--r-- 1 wy wy   848 Aug 22  1998 configure.in
-rw-r--r-- 1 wy wy 18043 Aug 22  1998 COPYING
-rw-r--r-- 1 wy wy  2118 Aug 22  1998 de
-rw-r--r-- 1 wy wy  4042 Aug 22  1998 diction.1.in
-rw-r--r-- 1 wy wy 10448 Aug 22  1998 diction.c
-rw-r--r-- 1 wy wy   795 Aug 22  1998 diction-en.msg
-rw-r--r-- 1 wy wy 19467 Aug 22  1998 en
-rw-r--r-- 1 wy wy  4510 Aug 23  1998 getopt1.c
-rw-r--r-- 1 wy wy 30140 Aug 23  1998 getopt.c
-rw-r--r-- 1 wy wy  4559 Aug 23  1998 getopt.h
-rw-r--r-- 1 wy wy  7832 Aug 22  1998 INSTALL
-rwxr-xr-x 1 wy wy  5585 Aug 22  1998 install-sh
-rw-r--r-- 1 wy wy  2008 Jan 17 12:26 Makefile
-rw-r--r-- 1 wy wy  1795 Aug 22  1998 Makefile.in
-rw-r--r-- 1 wy wy   845 Aug 22  1998 misc.c
-rw-r--r-- 1 wy wy   104 Aug 22  1998 misc.h
-rw-r--r-- 1 wy wy  1418 Aug 22  1998 README
-rw-r--r-- 1 wy wy  4597 Aug 22  1998 sentence.c
-rw-r--r-- 1 wy wy   120 Aug 22  1998 sentence-en.msg
-rw-r--r-- 1 wy wy   240 Aug 22  1998 sentence.h
-rw-r--r-- 1 wy wy  8905 Aug 22  1998 style.1
-rw-r--r-- 1 wy wy 17045 Aug 22  1998 style.c
-rw-r--r-- 1 wy wy   140 Aug 22  1998 style-en.msg
#6. 生成diction程序
wy@ZeroJean:~/diction-0.7$ make -v
GNU Make 4.3
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
wy@ZeroJean:~/diction-0.7$ make
sed -e s+/usr/share+../diction/share+ diction.1.in >diction.1
wy@ZeroJean:~/diction-0.7$ tree
.
├── config.cache
├── config.guess
├── config.h
├── config.h.in
├── config.log
├── config.status
├── config.sub
├── configure
├── configure.in
├── COPYING
├── de
├── diction
├── diction.1
├── diction.1.in
├── diction.c
├── diction-en.msg
├── diction.o
├── en
├── getopt1.c
├── getopt1.o
├── getopt.c
├── getopt.h
├── getopt.o
├── INSTALL
├── install-sh
├── Makefile
├── Makefile.in
├── misc.c
├── misc.h
├── misc.o
├── README
├── sentence.c
├── sentence-en.msg
├── sentence.h
├── sentence.o
├── style
├── style.1
├── style.c
├── style-en.msg
└── style.o

0 directories, 40 files
#7. make install 安装
wy@ZeroJean:~/diction-0.7$ make install
/usr/bin/install -c -m 755 -d ../diction/bin
/usr/bin/install -c -s diction ../diction/bin/diction
/usr/bin/install -c -s style ../diction/bin/style
/usr/bin/install -c -m 755 -d ../diction/share/diction
/usr/bin/install -c -m 644 de ../diction/share/diction/de
/usr/bin/install -c -m 644 en ../diction/share/diction/en
(cd ../diction/share/diction; rm -f C; ln en C)
/usr/bin/install -c -m 755 -d ../diction/man/man1
/usr/bin/install -c -m 644 diction.1 ../diction/man/man1/diction.1
/usr/bin/install -c -m 644 style.1 ../diction/man/man1/style.1
#8. 查看目录结构并查看是否运行
wy@ZeroJean:~/diction-0.7$ tree ../diction
../diction
├── bin
│   ├── diction
│   └── style
├── man
│   └── man1
│       ├── diction.1
│       └── style.1
└── share
└── diction
   ├── C
   ├── de
   └── en

5 directories, 7 files
wy@ZeroJean:~/diction-0.7$ which diction
/home/wy/diction/bin/diction  #程序安装位置

(2):MakeFile文件结构

# Generated automatically from Makefile.in by configure.
VERSION=	0.7
srcdir=		.
prefix=		../diction
exec_prefix=	${prefix}

BINDIR=		${exec_prefix}/bin
MANDIR=		${prefix}/man
SHAREDIR=	${prefix}/share
INSTALL=	/usr/bin/install -c
INSTALL_PROGRAM=${INSTALL}
INSTALL_DATA=	${INSTALL} -m 644
CC=		gcc #指定编译用的编辑器
CFLAGS=		-g -O2 -g -Wmissing-prototypes -Wstrict-prototypes -Wcast-qual -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-declarations -Wnested-externs -pedantic -fno-common
CPPFLAGS=	-I.  -DSHAREDIR=\"$(SHAREDIR)\" -DVERSION=\"$(VERSION)\"
LDFLAGS=	-g
LIBM=		-lm

all:		diction style diction.1
# 可执行文件diction依赖于文件diction.o sentence.o misc.o getopt.o getopt1.o
diction:	diction.o sentence.o misc.o getopt.o getopt1.o
		$(CC) -o $@ $(LDFLAGS) diction.o sentence.o misc.o \
		getopt.o getopt1.o $(LIBS)

style:		style.o sentence.o misc.o getopt.o getopt1.o
		$(CC) -o $@ $(LDFLAGS) style.o sentence.o misc.o \
		getopt.o getopt1.o $(LIBM) $(LIBS)

diction.1:	diction.1.in Makefile
		sed -e s+/usr/share+$(SHAREDIR)+ diction.1.in >$@

install:	all
		$(INSTALL) -m 755 -d $(BINDIR)
		$(INSTALL_PROGRAM) -s diction $(BINDIR)/diction
		$(INSTALL_PROGRAM) -s style $(BINDIR)/style
		$(INSTALL) -m 755 -d $(SHAREDIR)/diction
		$(INSTALL_DATA) de $(SHAREDIR)/diction/de
		$(INSTALL_DATA) en $(SHAREDIR)/diction/en
		(cd $(SHAREDIR)/diction; rm -f C; ln en C)
		$(INSTALL) -m 755 -d $(MANDIR)/man1
		$(INSTALL_DATA) diction.1 $(MANDIR)/man1/diction.1
		$(INSTALL_DATA) style.1 $(MANDIR)/man1/style.1

install.msg:
		gencat -o ${prefix}/share/locale/en_US/LC_MESSAGES/diction.cat diction-en.msg sentence-en.msg
		gencat -o ${prefix}/share/locale/en_US/LC_MESSAGES/style.cat style-en.msg sentence-en.msg

#{{{script}}}#{{{  clean
clean:
		rm -f *.out core *.o diction.1
#}}}
#{{{  clobber
clobber:	clean
		rm -f diction style config.cache config.h config.log config.status Makefile
#}}}
#{{{  tar
tar:		clobber
		(b=`pwd`; b=`basename $$b`; cd ..; tar zcvf $$b.tar.gz $$b/COPYING $$b/INSTALL $$b/Makefile.in $$b/README $$b/configure $$b/install-sh $$b/de $$b/en $$b/[a-z]*.*)
#}}}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值