linux shell脚本编写批处理

今天下午把打包好的镜像文件上传到公司服务器上,想在服务器上导入镜像,玩了会shell挺有意思的,把其中遇到的知识点以及问题列出来总结下。

问题引出

因为上传的镜像tar包很多,一个个使用docker load -i 显得很蠢,就想玩玩shell,在网上查了一下使用shell获取文件名的方法:

cur_dir="./"

for file_name in `ls ${cur_dir}`
        do
        if [ "${file_name##*.}"x = "tar"x ]; then
            tmp_file=`basename ${file_name}`
            docker load -i ${tmp_file}
        fi
        done

上面代码把知识点给到大家:

  • for循环结构
    这个还好理解,可以把他当成python代码,for里面的do done相当于for的代码体
  • ``意思是漂里面是可执行命令,等同于$()
  • ${}这个意思是使用shell中的变量,如果只是变量读取可以省略这个{}直接$
  • if使用结构:if [ state ] ; then fi
    这里注意一下:两个中括号中间必须有空格,包括if和中括号之间也要有!else结构:if [ state ]; then xxx elif [ state ] then xxx else fi
  • 中括号中间的state如果需要判等使用=单等号。
  • shell的单引号和双引号是有区别的!单引号不会解析其中的表达式,就如这个"${file_name##*.}" 这里如果使用单等号那么代表的就是纯纯的字符串。
  • "${file_name##*.}"x = "tar"x这个x没有特殊含义,仅是为了避免出现前面的字符串为空的情况下会报错,可以替换成任意字符。
  • "${file_name##*.}"x = "tar"x 中的 ##是字符串截取, .是截取方式,在我的代码中表示截取后缀, * 是舍弃位置,在截取方式前面表示舍弃.前面的字符串。有这几种类似符号:
    # 标记位为从前到后第一个匹配的位置
    ## 标记位为从前到后最后一个匹配的位置
    % 标记位为从后到前第一个匹配的位置
    %% 标记位为从后到前最后一个匹配的位置
优化

load成功之后,留下了一堆的tar包,为了给用户更好的体验给到一个交互shell:询问用户是否删除tar包

cur_dir="./"

for file_name in `ls ${cur_dir}`
        do
        if [ "${file_name##*.}"x = "tar"x ]; then
            tmp_file=`basename ${file_name}`
            docker load -i ${tmp_file}
        fi
        done

echo "remove tars?(y/n)"
read input
if [ "${input}"x = "y"x ]; then
    for file_name in `ls ${cur_dir}`
        do
        if [ "${file_name##*.}"x = "tar"x ]; then
            tmp_file=`basename ${file_name}`
            rm -f ${file_name}
        fi
        done
    echo "success"
fi

知识点㕛来了:

  • read读取shell输入字符串,并且存入input中。同时要注意下,我们这里的输入可能直接敲一个回车,那么这里的input就是null,所以也需要使用一个占位字符,避免null比较。

聪明的人应该可以看出代码有很大的重复程度,而且时间复杂度很高,这段判断文件后缀是否为tar的时间复杂度为O(2 * n * m),n是文件数量,m是文件名长度。

害怎么这么蠢呢 突然想到ls可以加个管道呀

优化:使用变量名存储后缀,这样不用多次修改后缀,便于测试用。

cur_dir="./"

suffix="txt"

for file_name in `ls ${cur_dir} | grep "${suffix}"`
        do
            tmp_file=`basename ${file_name}`
            echo $tmp_file
        done

echo "remove tars?(y/n)"
read input
if [ "${input}"x = "y"x ]; then
    for file_name in `ls ${cur_dir} | grep "$suffix"`
        do
        echo $file_name
        # rm -f $file_name
        done
    echo "success"
fi

搞定!好家伙,这个东西我竟然玩了两个小时,把正事都给忘了QwQ…
我还写了份用数组存储文件名的shell后来被覆盖不见了… 等有时间补上,或者大佬们在评论区里实现一下。

你可能感兴趣的:(linux,服务器,运维)