`

一些让人很容易忽视的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基础知识介绍

    CShell基础知识详解

    ### CShell基础知识详解 #### 一、引言 在之前的讨论中,我们已经涉及了许多Cshell的功能,例如命令别名、作业控制等。此外,任何一系列Cshell命令都可以存储在一个文件中,并通过调用Cshell来执行这些命令。这样...

    Linux Shell编程基础完整知识

    ### Linux Shell编程基础完整知识详解 #### 一、Shell脚本的基本构成与执行 Linux Shell编程是操作系统管理和自动化任务的核心技能之一。Shell脚本能够帮助用户执行一系列预定义的命令,实现复杂的操作流程自动化...

    linux shell 基础知识

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

    shell基础知识12篇

    以下是一些关于Shell的基础知识,对于初学者来说极具价值。 1. **Shell概述** - Shell的定义:Shell是一个命令行接口,它接收用户输入的命令并将其传递给操作系统内核执行。 - 主流Shell类型:Bash(Bourne-Again...

    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和unix的基础知识

    "shell基础知识.rar"这个压缩文件可能包含了更基础的Shell教程,涵盖了Shell的入门知识,如环境变量的设置、命令别名、管道(pipe)和重定向(redirect)的使用,以及常见Shell命令的介绍。这些基础知识对于初学者来...

    Shell脚本基础知识

    ### Shell脚本基础知识详解 #### 一、Shell脚本概览 **Shell脚本**是在Linux环境下的一种脚本语言,其功能强大且易于使用,在自动化任务处理、系统管理及编程辅助方面发挥着重要作用。尤其在配合C语言编程时,...

    shell编程-基础知识

    shell编程-基础知识

    shell编程基础知识

    **Shell编程基础知识** Shell编程是Linux/Unix操作系统中的一种脚本语言,用于自动化日常任务,进行系统管理,以及实现交互式命令行接口。对于初学者来说,掌握Shell编程能够极大地提高工作效率,理解其基本概念和...

    Linux运维-运维系统服务04-Shell脚本d2-shell基础知识-02SHELL介绍.mp4

    Linux运维-运维系统服务04-Shell脚本d2-shell基础知识-02SHELL介绍.mp4

    LinuxShell编程基础.pdf

    Linux Shell 编程基础 Linux Shell 编程基础是 ...Linux Shell 编程基础是 Linux 操作系统中一个非常重要的组件,掌握这些基础知识可以编写出更加复杂的 Shell 脚本,实现自动化任务、数据处理、系统管理等功能。

    学习shell的入门资料(shell十三问+shell基础十二篇)doc版

    1. **Shell基础知识** - **变量与赋值**:在Shell中,变量可以用来存储各种类型的数据,如字符串、整数。赋值使用等号`=`,如`NAME="John Doe"`。 - **命令行参数**:脚本可以接收命令行参数,它们在脚本内部用$0...

    unix及shell基础

    总的来说,掌握Unix和Shell的基础知识对于提高在命令行环境下工作的效率至关重要。理解Shell的用法和编写简单的脚本,能让你更好地利用Unix系统的强大功能。通过学习和实践,你可以更加自如地在Unix环境中导航和管理...

    shell基础编程实例

    shell基础编程的一些例子,供查阅使用,涉及到shell脚本使用的某些功能

Global site tag (gtag.js) - Google Analytics