`

一些让人很容易忽视的shell基础知识

阅读更多

http://blog.chinaunix.net/u2/86696/showart_2015126.html

 

一直觉得自己的shell脚本写的还可以, ms是有点自恋了, 最近在阅读一些高手写的脚本的时候, 却发现有点异常的吃力。 不禁忍不住问自己, 会几个条件判断, 几个循环就是shell编程的高手么? 于是乎再次来到CU shell版, 这里确实有很多很基础的知识, 都是自己不了解的, 有必要沉下心来深入学习/复习一下这些最基本的东西:

    当你在命令提示符后键入一个命令/命令列后, shell要做的工作是:
    1. 语法分析命令列
    2. 处理通配字符(wildcards)、重定向(redirection)、管道(pipes)和作业控制(job control)
    3. 搜寻并执行命令
    用户登陆后,用户命令同计算机交互的关系为:命令进程--->Shell程序--->UNIX内核--->计算机硬件
 
几个生僻的符号:
cmd &> file  # &> 表示把cmd的stdout和stderr都写入到file
cmd > file 2>&1  # 2>&1 基本同上, 记得2>&1之间不能有空格
n<>file  # 打开file用来读写, 并且分配文件描述符n给这个文件。 如果file不存在, 会自动创建
=~   # 正则表达式匹配, 这个必须是bash3.0以后的版本, 且必须用在双中括号中 [[]], 如[[ "$IP" =~ "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$" ]] && echo "ok" || echo "error"
 
 
==================================管道与sub-shell===================================
对bash来说, 在管道中的一个大括号中的代码段(块)是运行在一个 子shell中的.
  # ls | { read firstline; read secondline; }
  # echo "First line is $firstline; second line is $secondline"   # 这里看到的是空白
管道两边的代码”块“, 不仅仅只包括“大括号”括起来的块, 也包括while, for等循环中的”块“, 这就是为什么, 经常有人问起,为什么在while循环内赋值的变量, 在循环外面却没见生效, 并不是循环本身的原因, 而是因为这个循环在管道的两边哈

作为子进程的运行的管道, 不能够改变脚本的变量.
  1 variable="initial_value"
  2 echo "new_value" | read variable
  3 echo "variable = $variable"     # variable = initial_value
这里可以用read variable <<< "new_value"来替换
LANG=C &  或者export LANG=C &这样也不对当前shell产生影响,改不了LANG这个环境变量
如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止. 这种行为被叫做broken pipe, 并且这种状态下将发送一个SIGPIPE 信号.

bash中产生sub-shell的几种情况
1. cmd | { cmd_list1; ... cmd_listn; }
   { cmdlist; } | { cmd list; }
        注意这两种格式, 进程间的关系不一样, 试下{ sleep 10; } | { sleep 20; } 与 sleep 10 | { sleep 20; } 看下进程关系的差别
2. function func() { }
    func &
3. {} &
4. { func & } & 这样将产生2个sub-shell
5. (cmd1; cmd2)   # 这里的cmd必须大于1个(即cmd group)才会是subshell
6. su user   
==================================管道与sub-shell===================================
 
 
对于位置参数, 大于等于10的位置参数就必须用大括号括起来, 比如echo ${10}。 要访问命令行最后一个参数, 可以${!#}, 或者i=$#, ${!i}, ${!XX}表示间接引用
 
======================================代码块========================================
{} 使用花括号执行一系列的命令的时候, 如果没有换行, 记得每个领命后面都必须加上分号; 包括最后一个命令, 否则就会报错, 如:
$ { echo "xyz" }    # bash会认为的你输入还没有结束
$ vi test.sh
{ echo "xyz" }
$ ./test.sh
./test.sh: line 6: syntax error: unexpected end of file。 如果命令都用换行分开, 最后一个命令与}之间也换行, 就不需要分号
======================================代码块========================================
 
==============================here document========================================
1. 注意:  结束的limit string, 就是here document最后一行的limit string, 必须开始于第一个字符位置. 它的前面不能够有任何前置的空白. 而在这个limit string后边的空白也会引起异常问题. 空白将会阻止limit string的识别.
 
如, 有时候你为了对齐, 排版好看一些:
function test()
{
        cat << EOF
                hello, world
        EOF
        return 0
}
test
exit 0
 
执行这个脚本时候, 会报错: " syntax error: unexpected end of file ”, 这里必须把EOF放在行首才能避免这个错误
 
2. - 选项用来标记here document的limit string (<<-LimitString), 可以抑制输出时前边的tab
(不是空格). 这可以增加一个脚本的可读性.
 
3. here document 支持参数和命令替换. 所以也可以给here document的消息体传递不同的参数,
这样相应的也会修改输出. 当"limit string"被引用或转义那么就禁用了参数替换, 如
cat << 'EOF'
cat << "EOF"
cat << \EOF 都具有相同的效果, 此时here document里面的引用, 变量替换等都不会做相应的替换, 不过记得用来标识结束的 EOF 不需要加上这些转义之类的符号
 
4. 注释代码块, 比每行都加上#要好用多了
: << CommentHere
echo "hello, world"
# echo "hello"
CommentHere
==============================here document========================================
 
 
在命令行上,把感叹号"!"放在双引号里执行命令会出错(译者注:比如说:echo "hello!"). 因为感叹号被解释成了一个历史命令. 然而在一个脚本文件里,这么写则是正确的,因为在脚本文件里Bash的历史机制被禁用了。
 
 
bash的一些新特性:
[[ "abc" > "aba" ]] && echo true   # [[]] 不仅可以比较数值的大小, 还可以比较字符串大小


++++++++++字符串处理 
我们也可以对变量值里的字符串作替换:
${file/dir/path}:将第一个dir替换为path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:将全部dir替换为path:/path1/path2/path3/my.file.txt

${kk//[!0-9]/ }
 
 
========================bash里的冒号=================================
冒号:
    空命令, 是bash的内建命令, 什么也不干的命令, 相当与true, 返回0
    一般用法:
一. 死循环    while :  do   oper_lists; done
二. 在if/then中提供占位符 
        if condition
        then :          # 引发一个分支
        else
            oper_lists
        fi
三. : ${variable="xxx"}  # 在一个二元命令中提供一个占位符
    : ${variable:="xxx"}  # ${xxx:=} 对不同状态的变量赋值的时候, 一般要和: 结合使用
四. 跟here document结合注释bash代码块
    : << EOF
    echo "hello, world"
    ......
    EOF
    这个有点类似于c/cpp里的利用编译预处理 #if 0   ....  #endif来注释一段大的代码块
========================bash里的冒号=================================
 
 
ps 的时候看到的bash为什么之前有一个-呢?
-bash
这个表示这是一个登录shell
如果只是 bash, 表示一个非登录shell, 用su xxx试试, 然后ps一下
 
 
 
 
===========================函   数===========================
1. 在函数中, 声明的变量, 如果没有特别指明是local的, 在函数体外也可以用
2. 在函数中调用另外一个函数,  被调用的函数可以在调用的函数之后再定义/声明(bash中没有函数声明的概念)。 比如:
function a()
{
    echo "i'm a"
    b
}
 
function b()
{
     echo "i'm b"
}
 
3. 但是如果有个公共函数库, 你必须先调用公共库, 才能执行公共库中的函数, 比如:
. ./functions
func_in_functions
 
而不能
func_in_functions
. ./functions
===========================函   数===========================
分享到:
评论

相关推荐

    shell基础知识

    最近在学习shell,找了很多资料,这个是其中不错的shell基础知识讲解,虽然比较基础,但是很容易懂~

    shell讲解基础知识

    shell基础 umask chomod 权限更改 定时任务 解压缩

    shell基础知识介绍

    shell基础知识介绍

    Linux Shell编程基础完整知识

    Linux Shell编程基础完整知识,基础的、

    Unix基础知识与Shell编程

    主要介绍了UNIX的基础知识,以及shell编程的初阶知识,对UNIX学习的入门以及Shell编程很有帮助

    shell基础十二篇

    ,[]等)shell基础5:输入/输出(echo,read,cat,管道,tee,重定向等)shell基础8:文本过滤工具(grep) shell基础9:awk 64 shell基础10:sed 94 Shell基础11:文件分类、合并和分割(sort,uniq,join,cut,paste...

    linux shell 基础知识

    linux shell 基础知识 ,word版,看着更方便。。。。。

    Linux网络操作系统基础:shell编程基础.pptx

    熟悉 Shell 基础知识 掌握 Shell 脚本的基本操作 结合实际案例展示 Shell 脚本编写的最佳实践 ;Linux 中的文本流;输出重定向;输入重定向;管道;熟悉 Shell 基础知识 掌握 Shell 脚本的基本操作 结合实际案例展示 ...

    CShell基础知识详解

    cshell的基础知识,描述了基本命令的应用,编程基础等等,帮你更快的解决编程基础问题

    Shell脚本编程基础知识

    Shell脚本编程基础知识: 掌握创建 shell 脚本的基本步骤 学会使用条件测试 掌握 if 条件结构与 case 选择结构 掌握 for 循环、while 循环和 until 循环结构 学会 shift 命令的使用 学会 shell 脚本的调试

    Unix shell 基础知识普及

    5. SHELL 输入与输出 6. 命令执行顺序 7. 正则表达式介绍 文本过滤 8. GREP 家族 9. AWK 介绍 10. sed 用法介绍 11. 合并与分割 12. tr 用法 13. 登录环境 14. 环境与 SHELL 变量 特定s h e l l变量 15. 引号 16. ...

    SHELL基础十二篇

    SHELL基础 十二篇 SHELL基础 十二篇 SHELL基础 十二篇

    shell 基础知识、介绍、根据线上课程

    shell 基础知识、介绍、根据线上课程

    shell基础知识12篇

    从网络上整理的shell基础,入门shell非常有帮助

    Shell基础知识解析.doc

    shell对于很多的初学者来说Shell其实是一个非常陌生的东西,在说shell之前我们先引用一些基础的知识。

    Shell脚本基础知识

    描述Shell脚本的基础知识,更好地配合C语言编程。

    Shell基础十二篇

    Shell基础十二篇,unix,Shell基础十二篇,unix

Global site tag (gtag.js) - Google Analytics