Shell 简明教程 快速上手

作为一个 Java 程序员,Go 爱好者,自然免不了天天和 Linux 打交道,也曾经写过一点点 shell 脚本,但是对那个反人类的语法深感厌恶,空格不对都不行。无奈项目需要一定要用 shell 来实现一个工具,学习的过程总是不那么顺风的,不过搞完之后也觉得没那么讨厌了。整理一下几天所得,希望能让一个从没写过 shell 但是还挺熟悉 Linux 的可以立马完成一个可用的脚本。

  1. 执行顺序

脚本顺序执行,原来怎么敲命令的就怎么写

  1. 变量赋值

    # 变量赋值时等号两边不能有空格
    # 单引号是固定字符串
    pa='string'
    
    # 双引号可包含变量
    pb="ps is ${pa}"
    
    # 接受命令返回
    pc=`ls -alh`
    
  2. 数组及其遍历

    arr=(aa bb cc dd ff)
    # 通过下标访问
    for ((i=0; i<5; i++))
    do
        echo "$i: ${arr[$i]}"
    done
    
    # 遍历访问
    for s in ${arr[@]}
    do
    echo "  $s"
    done
    
    # 空格分隔的字符串也能遍历,但是不能像上面的方式一样用下标访问元素
    arr2='a1 a2 a3 a4 a5'
    for s in ${arr2}
    do
    echo ${s}
    done
    
  3. 条件判断

    # shell 脚本都是指令,if 的语句一定要注意空格
    # 第一种写法,下面输出 ok
    if [[ 10 -gt 3 ]]; then echo ok; else echo no; fi
    
    # 第二种, ** 注意(): 下面输出 ok
    if [ 2 > 3 ]; then 
        echo ok
    fi
    
    # 第三种, 下面输出 no
    if [[ 2 > 3 ]]
    then 
        echo ok
    else 
        echo no
    fi
    
  4. 定义函数

    res=0
    echo $res
    
    add() {
        ((res = $1 + $2))
    }
    add 12 13
    echo $res
    
  5. $? 说明

    # $?接受的是上一条命令执行后的返回值
    ls /home
    
    # 下面的输出是 0
    echo $?
    
    testReurn() {
        return 8
    }
    testReurn
    
    # 下面的输出是 8 
    echo $?
    
  6. 字符串操作

    a='stringA'
    b='stringB'
    
    # 判断是否相等,下面输出 no
    if [[ $a == $b ]]; then echo yes; else echo no; fi
    
    # 字符串拼接, 下面输出 yes
    if [[ 'stringAstringB' == "${a}${b}" ]]; then echo yes; fi
    
    # 取字符串长度, 下面输出 7
    echo ${#a}
    
    # 截取字符串, 下面输出  string, ing
    echo "${a:0:6}, ${a:3:3}"
    
    # 判断两个字符串是否有相同前缀, 下面输出 yes
    if [[ ${a:0:5} == ${b:0:5} ]]; then echo yes; else echo no; fi
    
    # 字符串切分为数组, IFS 变量指定分隔符, 分隔符前后空格会被略去
    IFS=, read -r -a arr <<< 'a,b  ,c, d,g e,   ss'
    for str in ${arr[@]}; do echo "'${str}'"; done
    
  7. 文件和目录判断

    if [[ -f $filename ]]; then
      echo "$filename 是一个文件"
    elif [[ -d $filename ]]; then
      echo "$filename 是一个目录"
    elif [[ -p $filename ]]; then
      echo "$filename 是一个管道文件"
    elif [[ -S $filename ]]; then
      echo "$filename 是一个 sokcet 文件"
    elif [[ -b $filename ]]; then
      echo "$filename 是 block device"
    elif [[ -c $filename ]]; then
      echo "$filename 是 character device"
    fi
    if [[ -L $filename ]]; then
      echo "$filename 是一个软链接"
    fi
    # 对于软链接,使用-L测试时,当链接指向的目标文件不存在时会返回false
    if [[ -L $filename || -e $filename ]]; then
      echo "$filename 存在 (可能是失效的链接)"
    fi
     
    if [[ -L $filename && ! -e $filename ]]; then
      echo "$filename 是失效的软链接"
    fi
    
  8. 内容既输出到控制台也输出到文件里

    
    echo 'ok'| tee -a bb.log
    
  9. 处理退出信号

    trap "rm -f ${lock_file}; echo 'exited ok.'" SIGINT SIGQUIT
    
    # SIGHUP:从终端终止或退出正在前台运行的进程
    # SIGINT:从键盘按下 Ctrl-C
    # SIGQUIT:从键盘按下 Ctrl-\
    # SIGTERM :软件终止信号
    
  10. 处理参数

    if [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX ( brew install gnu-getopt )
        getopt_cmd="$(brew --prefix gnu-getopt)/bin/getopt"
    else
        # linux-gnu
        getopt_cmd="getopt"
    fi
    long_opts="once,name:,note:"
    
    opts=$($getopt_cmd -n $0 -o - --long $long_opts -- "$@")
    
    eval set -- "$opts"
    
    while : 
    do
        case "$1" in
        --once)
            once="true" ; shift 1 ;;
        --name)
            name=$2  ; shift 2 ;;
            --note)
                note=$2  ; shift 2 ;;
        --)
            shift ; break ;;
        *)
        echo "参数错误" ; exit 1 ;;
    esac
    done
    echo "once: ${once:-no}, name: ${name}, note: ${note}"
    
  11. MySQL 查询

    std_log='/var/log/test.log'
    err_log='/var/log/test.err.log'
    
    user='root'
    pwd=''
    host='127.0.0.1'
    db='mysql'
    
    exec_sql() {
        echo "exec_sql: $1" | tee -a ${std_log}
        mysql -u${user} -p${pwd} -h${host} -D${db} -s -N -e "$1" | tee -a ${std_log}
    }
    exec_sql "show databases"
    
  12. 标准输入输出重定向

shell中,每个进程都和三个系统文
件相关联:标准输入stdin,标准输出stdout和标准错误stderr,三个系统文件的文件描述符分别为0, 1, 2
在使用 mysql 命令获取结果时会有一些警告信息
mysql: [Warning] Using a password on the command line interface can be insecure.
但是我要得到命令的结果不需要这些警告, 这个时候就需要重定向错误输出到其他地方
num=`mysql -u${user} -p${pwd} -h${host} -D${db} -s -N -e "${count_sql}" 2>${err_log}

注意

此为个人这一周以来的小总结,并非专业的 shell 教程,旨在能帮助懂编程的人不会 shell 的能快速上手,少走一些我趟过的坑,减少一些搜索。
有些原理我也不是太清楚,以后需要的时候才会去系统学习吧,现在这些已经能完成任务了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容