shell编程lesson09

news/2024/5/18 21:56:25

位置参数

        之前一直没有涉及程序接收和处理命令行选项及实参的能力,本节将介绍程序访问命令行内容的shell功能

访问命令行

        shell提供了一组名为位置参数的变量,用于存储命令行中的关键字,这些变量分别命名0~9,可以通过以下方式访问这些变量

#!/bin/bash

# posit-param:script to view command line parameters

echo "
\$0 = $0
\$1 = $1
\$2 = $2
\$3 = $3
\$4 = $4
\$5 = $5
\$6 = $6
\$7 = $7
\$8 = $8
\$9 = $9
"

在没有任何命令行实参的情形下执行此脚本,运行结果如下

$0 = a.sh
$1 = 
$2 = 
$3 = 
$4 = 
$5 = 
$6 = 
$7 = 
$8 = 
$9 = 

可以看到,即便没有任何的命令行实参,变量$0总是会存储所执行程序所在的文件名

!!!使用参数扩展技术,用户实际可以获取多于9个的位置参数,为标明一个大于9的数字,需要将数字用大括号括起来,例如${10}、${56}、${256}

确定实参的数目

shell还提供了变量 $# 以给出命令行参数的个数。

#!/bin/bash

# posit-param:script to view command line parameters

echo "
Number of arguments:$#
\$0 = $0
\$1 = $1
\$2 = $2
\$3 = $3
\$4 = $4
\$5 = $5
\$6 = $6
\$7 = $7
\$8 = $8
\$9 = $9
\$10 = ${10}
"

($0 :表示执行脚本名称;$# :表示命令行参数个数)

shift——处理大量的实参

#!/bin/bash

# posit-param2:script to display all arguments

count=1

while [[ $# -gt 0 ]];do
        echo "Argument $count: $1"
        count=$((count+1))
        shift
done

        shift提供了一种机制,每次执行shift命令后,所有的参数值均“下移一位”。即变量$2的值会赋给变量$1,而$3的值则会赋给变量$2,以此类推,全部“下移一位”,并且变量$#的值同时减1。

        通过shift命令,我们只需要处理一个参数即可,即$1。

        以上脚本,创建了一个循环,只要还存在1个实参,循环就不停止。首先输出当前的实参,其次,每次循环迭代一次,就将变量count值加1,代表处理过的实参数目。最后,执行shift命令使得$1载入下一个实参的值。

一个简单的应用程序

#!/bin/bash

# file_info:simple file information program

PROGNAME=$(basename $0)
while [[ $# -gt 0 ]];do
if [[ -e $1 ]];then
        echo -e "\nFile Type:"
        file $1
        echo -e "\nFile Status:"
        stat $1
else
        echo "$PROGNAME: usage:$PROGNAME file" >&2
        exit 1
fi
shift
done

列出指令路径下实参(路径下的各类文件)的文件类型(file命令)和文件状态(stat命令)。

在shell函数中使用位置参数

        如同位置参数可以向脚本传递实参一样,位置参数也可以用于shell函数实参的传递

file_info(){
    # file_info:functiono to display file information
    if [[ -e $1 ]];then
        echo -e "\nFile Type:"
        file $1
        echo -e "\nFile Status:"
        stat $1
    else
        echo "$FUNCNAME: usage: $FUNCNAME file" >&2
        return 1
    fi
}

        函数的返回状态用return,如果不是函数则用exit命令。  tips

        我们不仅可以在普通脚本中传递位置参数给函数,也可以在.bashrc文件中维护使用位置参数的函数。

        需要注意的是,PROGNAME变量被换成了名为FUNCNAME的shell变量。shell会自动更新FUNCNAME以追踪当前执行的shell函数。

        $0变量表示的是执行脚本的脚本文件名称;$FUNCNAME变量用于函数中,表示的是所在函数的名称。注意区别。

处理多个位置参数

        有时候我们会把所有位置参数当做一个整体来处理。

shell为这项功能提供了两种特殊的参数。两种参数都能扩展为一个完整的位置参数列,但是又有着微妙的区别。

参数描述
$*可扩展为从1开始的位置参数列。当包括在双引号内时,扩展为双引号引用的由全部位置参数构成的字符串,每个位置参数以IFS shell变量的第一个字符(默认情况下为空格)间隔开
$@可扩展为从1开始的位置参数列。当包含在双引号内时,将每个位置参数扩展为双引号引用的单独单词
#!/bin/bash

# posit-params3:script to demonstrate $* and $@

print_params(){
        echo "\$1 = $1"
        echo "\$2 = $2"
        echo "\$3 = $3"
        echo "\$4 = $4"
}

pass_params(){
        echo -e "\n" '$* :';print_params $*
        echo -e "\n" '"$*" :';print_params "$*"
        echo -e "\n" '$@ :';print_params $@
        echo -e "\n" '"$@" :';print_params "$@"
}

pass_params "word" "words with spaces"

执行结果


 $* :
$1 = word
$2 = words
$3 = with
$4 = spaces

 "$*" :
$1 = word words with spaces
$2 = 
$3 = 
$4 = 

 $@ :
$1 = word
$2 = words
$3 = with
$4 = spaces

 "$@" :
$1 = word
$2 = words with spaces
$3 = 
$4 = 

"$*" 和 "$@" 都产生了包含4个单词的结果。"$*"产生的是只包含一条字符串的结果,即word words with spaces。"$@"产生的则是包含了两条字符串的结果,即word和words with spaces。

        因为"$@"保持了每个位置参数的完整性,没有破坏位置参数的结构,所以"$@"是大多数情况下的使用格式!

更完整的应用程序

        在位置参数的帮助下,用户可以写出功能性更强的脚本。通常,对于重复性的任务,位置参数使得用户可以写出很有帮助的shell函数,并放置在用户的.bashrc文件中。

        回到系统信息报告生成器脚本,如下

#!/bin/bash

# sys_info_page: program to output a system information page

PROGNAME=$(basename $0)
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIME_STAMP="Generated $CURRENT_TIME ,by $USER"

report_uptime () {
        cat <<- _EOF_
                <H2>System Uptime</H2>
                <PRE>$(uptime)</PRE>
                _EOF_
        return
}
report_disk_space () {
        cat <<- _EOF_
                <H2>Disk Space Utilization</H2>
                <PRE>$(df -h)</PRE>
                _EOF_
        return
}
report_home_space () {
        if [[ $(id -u) -eq 0 ]];then
                cat <<- _EOF_
                        <H2>Home Space Utilization(All Users)</H2>
                        <PRE>$(du -sh /home/*)</PRE>
                        _EOF_
        else
                cat <<- _EOF_
                        <H2>Home Space Utilization ($USER)</H2>
                        <PRE>$(du -sh $HOME)</PRE>
                        _EOF_
        fi
        return
}

usage () {
        echo "$PROGNAME: usage: $PROGNAME [-f file| -i ]"
        return
}

write_html_page () {
        cat <<- _EOF_
                <HTML>
                        <HEAD>
                                <TITLE>$TITLE</TITLE>
                        </HEAD>
                        <BODY>
                                <H1>$TITLE</H1>
                                <P>$TIME_STAMP</P>
                                $(report_uptime)
                                $(report_disk_space)
                                $(report_home_space)
                        </BODY>
                </HTML>
                _EOF_
        return
}

# process command line option

interactive=
filename=

while [[ -n $1 ]];do
        case $1 in
                -f | --file)    shift
                                filename=$1
                                ;;
                -i | --interactive)     interactive=1
                                        ;;
                -h | --help)    usage
                                exit
                                ;;
                *)      usage >&2
                        exit 1
                        ;;
        esac
        shift
done

# interactive mode
if [[ -n $interactive ]];then
        while true;do
                read -p "Enter name of output file: " filename
                if [[ -e $filename ]];then
                        read -p "'$filename' exists. Overwrite? [y/n/q] > "
                        case $REPLY in
                                Y|y)    break
                                        ;;
                                Q|q)    echo "Program terminated."
                                        exit
                                        ;;
                                *)      continue
                                        ;;
                        esac
                elif [[ -z $filename ]];then
                        continue
                else
                        break
                fi
        done
fi

# output html page

if [[ -n $filename ]];then
        if touch $filename && [[ -f $filename ]];then
                write_html_page > $filename
        else
                echo "$PROGNAME:Cannot write file '$filename'" >&2
                exit 1
        fi
else
        write_html_page
fi

需要多看以上脚本,理解与学习其编写脚本的设计思想。


http://www.niftyadmin.cn/n/393837.html

相关文章

chatgpt赋能python:Python只取小数

Python只取小数 Python是一种高级编程语言&#xff0c;被广泛应用于数据科学、人工智能、Web开发等领域。在数据分析和计算中&#xff0c;往往需要只保留小数&#xff0c;本文将介绍如何使用Python只取小数&#xff0c;并提供相关代码。 什么是小数? 在数学中&#xff0c…

C#,码海拾贝(33)——约化“一般实矩阵”为“赫申伯格矩阵”的“初等相似变换法”之C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 矩阵类 /// 作者&#xff1a;周长发 /// 改进&#xff1a;深度混淆 /// https://blog.csdn.net/beijinghorn /// </summary> public partial class Matrix {…

Netty之EventLoop 解读

是什么 EventLoop &#xff08;事件循环对象&#xff09;本质是一个单线程执行器&#xff08;同时维护了一个 Selector&#xff09;&#xff0c;里面有 run 方法处理 Channel 上源源不断的 io 事件。 它的继承关系比较复杂 一条线是继承自 j.u.c.ScheduledExecutorService 因…

网络io、io多路复用select/poll/epoll、基于事件驱动的reactor

一、网络IO请求 网络I/O请求是指在计算机网络中&#xff0c;向其他主机或服务器发送请求或接收响应的操作。这些请求可以包括获取网页、下载文件、发送电子邮件等。网络I/O请求需要使用合适的协议和通信方式来进行数据传输&#xff0c;例如HTTP、FTP、SMTP等。 要完成一个完整…

solr快速上手:配置从mysql同步数据(五)

0. 引言 上一节我们已经配置了新的索引&#xff0c;但是数据还是手动添加的&#xff0c;并没有实现自动从数据库同步&#xff0c;所以这一节&#xff0c;继续来实现从mysql同步数据到solr solr快速上手&#xff1a;solr简介及安装&#xff08;一&#xff09; solr快速上手&a…

解决record on line 2: wrong number of fields

背景 基于"encoding/csv"库解析。 共解析多个文档&#xff0c;只有这一个解析有问题&#xff0c;所用代码一致&#xff0c;进行比较后 发现该文档和其它文档不同&#xff0c;其它文档是第一行就是列名&#xff0c;下面都是数据&#xff1b; 而这个文档前两行有数据且…

前端045_单点登录SSO_实现流程

单点登录SSO_实现流程 1、背景2、基于同域下 Cookie 实现 SSO1、背景 在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,运营人员每天用自己的账号登录,很方便。 但随着企业的发展,用到的系统随之增多,运营人员在操作不同的系统时,需要…

Linux之理解文件系统——文件的管理

文章目录 前言一、磁盘1.磁盘的物理结构2.磁盘的存储结构3.磁盘的逻辑结构 二、文件系统与inode1.文件在磁盘中是如何存储的&#xff1f;2.对文件进行操作 三、软硬链接1.软链接创建软链接&#xff1a;inode删除软链接&#xff1a;软链接的作用&#xff1a; 2.硬链接创建硬链接…