栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > Cocos2d-x

❤️肝下25万字的《决战Linux到精通》笔记,你的Linux水平将从入门到入魔❤️【建议收藏】

Cocos2d-x 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

❤️肝下25万字的《决战Linux到精通》笔记,你的Linux水平将从入门到入魔❤️【建议收藏】

涉及的内容情况参看下面的目录:

文章目录
  • 操作系统的发展史
    • Unix
    • Minix
    • Linux
    • 操作系统的发展
    • Minix没有火起来的原因
  • Linux介绍
    • Linux内核&发行版
      • Linux内核版本
      • Linux发行版本
    • 类Unix系统目录结构
    • Linux目录
    • 用户目录
  • 命令行基本操作
    • 命令使用方法
    • 查看帮助文档
      • help
      • man(manual)
    • tab键自动补全
    • history游览历史
    • 命令行中的ctrl组合键
  • Linux命令
    • 权限管理
      • 列出目录的内容:ls
      • 显示inode的内容:stat
      • 文件访问权限
      • 修改文件权限:chmod
      • 修改文件所有者:chown
      • 修改文件所属组:chgrp
    • 文件内容查看
      • 基本显示:cat、tac
      • 显示行号:nl
      • 分屏显示:more、less
      • 取首尾n行:head、tail
    • 文件管理
      • 输出重定向:>
      • 管道:|
      • 清屏:clear
      • 切换工作目录: cd
      • 显示当前路径:pwd
      • 创建目录:mkdir
      • 删除文件:rm
      • 建立链接文件:ln
      • 文本搜索:grep
      • 查找文件:find
      • 拷贝文件:cp
      • 移动文件:mv
      • 归档管理:tar
      • 文件压缩解压:gzip、bzip2
      • 文件压缩解压:zip、unzip
      • 查看命令位置:which
    • 用户和用户组管理
      • 查看当前用户:whoami
      • 查看登录用户:who
      • 退出登录账户: exit
      • 添加用户账号:useradd
      • 修改用户:usermod
      • 设置用户密码:passwd
      • 删除用户:userdel
      • 切换用户:su
      • 以root身份执行指令:sudo
      • 添加、删除组账号:groupadd、groupdel
      • 用户组管理:groupmod
    • 系统管理
      • 查看当前日历:cal
      • 显示或设置时间:date
      • 查看网络状态:netstat
      • 查看进程信息:ps
      • 以树状图显示进程关系:pstree
      • 动态显示进程:top
      • 终止进程:kill
      • 关机重启:reboot、shutdown、init
      • 检测磁盘空间:df
      • 检测目录所占磁盘空间:du
      • 查看或配置网卡信息:ifconfig
      • 测试远程主机连通性:ping
    • Linux 磁盘管理
      • df
      • du
      • fdisk
      • 磁盘格式化
      • 磁盘检验
      • 磁盘挂载与卸除
    • Linux管道命令
      • wc - 统计字数
      • cut - 列选取命令
      • grep - 行选取命令
      • sort - 排序
      • uniq - 去重
      • tee - 同时输出多个文件
      • tr - 替换指定的字符
      • join - 文件按行连接
      • paste-将多个文件对应行链接在一起
      • split - 文件切割
      • xargs - 参数代换
  • linux命令练习
    • 常用命令
    • 系统命令
    • 用户和组
    • 权限
    • 帮助文档
    • VIM
    • 查找
    • 打包与压缩
    • 正则表达式
    • 输入输出重定向
    • 进程控制
    • 其他命令
      • 远程文件复制:scp
      • locate查找
      • which命令
      • echo
      • 设置或显示环境变量:export
      • 修改主机名&ip地址
      • mount挂载
      • ssh免密登陆
    • 批量添加用户
      • 与用户账号有关的系统文件
      • 实操
    • crontab的使用
  • 特殊权限
    • 三种特殊的权限
      • SetUID(suid)
      • setGID(sgid)
      • sticky(sbit)粘滞位
    • chattr权限
      • lsattr:查看特殊权限
      • chattr:设置特殊权限
    • 掩码umask
      • umask的作用
      • umask是如何改变新文件的权限
      • 永久修改umask
  • linux软件安装
    • Ubuntu软件安装与卸载
      • 更新Ubuntu软件下载地址
      • Ubuntu软件操作的相关命令
    • yum安装命令
      • 更新国内yum源
      • yum常用命令
      • yum在线安装MySQL5.7
      • rpm
    • Linux的基本配置
      • 安装JDK
      • 制作本地YUM源
  • Shell编程
    • 入门
      • 运行Shell脚本
      • 编写一个快捷创建shell脚本的命令
      • echo命令
        • 显示换行
        • 显示不换行
      • printf 命令
      • Shell 注释
    • Shell变量
      • 定义变量
      • 使用变量
      • 只读变量
      • 删除变量
      • 变量类型
    • Shell 函数
    • 文件包含
    • shell数据类型
      • 字符串
      • 数组
        • 定义数组
        • 读取数组
        • 获取数组的长度
      • Shell传递参数
    • Shell基本运算符
      • 算术运算符
      • 关系运算符
      • 布尔运算符
      • 逻辑运算符
      • 字符串运算符
      • 文件测试运算符
    • test命令
      • 数值测试
      • 字符串测试
      • 文件测试
    • Shell 流程控制
      • if else判断语句
      • for循环
      • while循环
      • 无限循环
      • until 循环
      • case
      • 跳出循环
    • Shell输入/输出重定向
      • 输出重定向
      • 输入重定向
      • 重定向深入讲解
      • Here Document
      • /dev/null 文件
    • 实例
      • 杨辉三角:
      • sum()&max():
      • 99乘法表:
  • 文本编辑命令
    • cut命令
    • sed命令
      • 元字符集
      • a|i:在指定行位置添加行
      • d:删除指定行
      • c:替换指定行
      • p:仅显示指定行
      • s:字符串替换
      • y:单字符替换
      • `hHgG`模式空间&保持空间
      • 多次指定`-e`选项进行多点编辑
      • 选项`-i`直接修改文件内容
    • awk命令
      • 基本用法
        • `-F`指定分割字符
        • `-v`设置变量
        • `-f`指定awk脚本
      • AWK工作原理
        • 运算符
        • 输出顺序号 NR, 匹配文本行号
        • 指定输出分割符
        • 忽略大小写
      • 正则字符串匹配
      • 一些实例
    • awk编程
      • 条件语句IF&ELSE
      • 循环语句For&While
      • awk数组
      • AWK 用户自定义函数
      • AWK 内置函数
      • 算数函数
        • 字符串函数
        • 时间函数
        • 位操作函数
        • 其他函数
  • vim全套笔记
    • VIM快速复习
      • 什么是 vim?
      • 按:冒号即可进入last line mode
      • 从command mode进入Insert mode
      • 按ESC键退回command mode
      • 多行编辑,vim支持,vi不支持
      • vim练习
    • vi/vim的三种模式
      • 命令模式
      • 输入模式
      • 底行模式
    • vim基础操作
      • 进入输入模式(Insert mode)
      • 进入替换模式(Replace mode)
      • 命令模式下常用命令
        • 移动光标
        • 删除操作
        • 撤销&复原&重复
        • 复制&粘贴
        • 合成行
        • 搜索
        • 替换
      • 底行命令模式的常用操作
      • 可视模式
  • Linux系统启动过程
    • 加载内核
    • 启动初始化进程init
    • 确定运行级别
    • 加载开机启动程序
    • 用户登录
    • 图形模式与文字模式的切换方式
    • login shell
    • Linux关机
    • 计算机启动的流程
      • 第一阶段:BIOS
      • 第二阶段: 主引加粗样式导记录
      • 第三阶段:硬盘启动
      • 第四阶段:操作系统
    • 单用户模式修改Centos系统root密码
    • 救援模式修改Ubuntu系统root密码
  • 虚拟机
    • 三种网络模式
    • 常见问题
      • 修改静态地址后发现无法ping外网
      • 虚拟机克隆后eth0消失

操作系统的发展史 Unix
  • 1965年之前,电脑只有军事或者学院的研究机构碰的起,当时大型主机至多能提供30台终端(30个键盘、显示器)的连接。
  • 1965年左后由贝尔实验室、麻省理工学院 以及 通用电气共同发起了Multics项目,想让大型主机支持300台终端
  • 1969年前后这个项目进度缓慢,资金短缺,贝尔实验室退出了研究
  • 1969年从这个项目中退出的Ken Thompson当时在实验室无聊时,为了让一台空闲的电脑上能够运行“星际旅行”游行,在8月份左右趁着其妻子探亲的时间,用了1个月的时间编写出了 Unix操作系统的原型
  • 1970年,美国贝尔实验室的 Ken Thompson,以 BCPL语言 为基础,设计出很简单且很接近硬件的 B语言(取BCPL的首字母),并且他用B语言写了第一个UNIX操作系统。
    因为B语言的跨平台性较差,为了能够在其他的电脑上也能够运行这个非常棒的Unix操作系统,Dennis Ritchie和Ken Thompson 从B语言的基础上准备研究一个更好的语言
  • 1972年,美国贝尔实验室的 Dennis Ritchie在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言
  • 1973年初,C语言的主体完成。Thompson和Ritchie迫不及待地开始用它完全重写了现在大名鼎鼎的Unix操作系统
Minix

因为AT&T(通用电气)的政策改变,在Version 7 Unix推出之后,发布新的使用条款,将UNIX源代码私有化,在大学中不再能使用UNIX源代码。Andrew S. Tanenbaum(塔能鲍姆)教授为了能在课堂上教授学生操作系统运作的实务细节,决定在不使用任何AT&T的源代码前提下,自行开发与UNIX兼容的操作系统,以避免版权上的争议。他以小型UNIX(mini-UNIX)之意,将它称为MINIX。

Linux

因为Minix只是教学使用,因此功能并不强,因此Torvalds利用GNU的bash当做开发环境,gcc当做编译工具,编写了Linux内核-v0.02,但是一开始Linux并不能兼容Unix,即Unix上跑的应用程序不能在Linux上跑,即应用程序与内核之间的接口不一致,因为Unix是遵循POSIX规范的,因此Torvalds修改了Linux,并遵循POSIX(Portable Operating System Interface,他规范了应用程序与内核的接口规范); 一开始Linux只适用于386,后来经过全世界的网友的帮助,最终能够兼容多种硬件

操作系统的发展


Minix没有火起来的原因

Minix的创始人说,MINIX 3没有统治世界是源于他在1992年犯下的一个错误,当时他认为BSD必然会一统天下,因为它是一个更稳定和更成熟的系统,其它操作系统难以与之竞争。因此他的MINIX的重心集中在教育上。四名BSD开发者已经成立了一家公司销售BSD系统,他们甚至还有一个有趣的电话号码1-800-ITS-UNIX。然而他们正因为这个电话号码而惹火上身。美国电话电报公司因电话号码而提起诉讼。官司打了三年才解决。在此期间,BSD陷于停滞,而Linux则借此一飞冲天。他的错误在于没有意识官司竟然持续了如此长的时间,以及BSD会因此受到削弱。如果美国电话电报公司没有起诉,Linux永远不会流行起来,BSD将统治世界。

Linux介绍 Linux内核&发行版 Linux内核版本

内核(kernel)是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一个在裸设备与应用程序间的抽象层。

Linux内核版本又分为稳定版和开发版,两种版本是相互关联,相互循环:

  • 稳定版:具有工业级强度,可以广泛地应用和部署。新的稳定版相对于较旧的只是修正一些bug或加入一些新的驱动程序。
  • 开发版:由于要试验各种解决方案,所以变化很快。

内核源码网址:http://www.kernel.org 所有来自全世界的对Linux源码的修改最终都会汇总到这个网站,由Linus领导的开源社区对其进行甄别和修改最终决定是否进入到Linux主线内核源码中。

Linux发行版本

Linux发行版 (也被叫做 GNU/Linux 发行版) 通常包含了包括桌面环境、办公套件、媒体播放器、数据库等应用软件。

目前市面上较知名的发行版有:Ubuntu、RedHat、CentOS、Debian、Fedora、SuSE、OpenSUSE、Arch Linux、SolusOS 等。

类Unix系统目录结构

Unix没有盘符这个概念,只有一个根目录/,所有文件都在它下面

Linux目录

  • /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录。所有的东西都是从这里开始。当你在终端里输入“/home”,你其实是在告诉电脑,先从/(根目录)开始,再进入到home目录。
  • /bin: /usr/bin: 可执行二进制文件的目录,如常用的命令ls、tar、mv、cat等。
  • /boot:放置linux系统启动时用到的一些文件,如Linux的内核文件:/boot/vmlinuz,系统引导管理器:/boot/grub。
  • /dev:存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,常用的是挂载光驱 mount /dev/cdrom /mnt。
  • /etc:系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有 /etc/inittab、/etc/fstab、/etc/init.d、/etc/X11、/etc/sysconfig、/etc/xinetd.d。
  • /home:系统默认的用户家目录,新增用户账号时,用户的家目录都存放在此目录下,表示当前用户的家目录,edu 表示用户 edu 的家目录。
  • /lib: /usr/lib: /usr/local/lib:系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助。
  • /lost+fount:系统异常产生错误时,会将一些遗失的片段放置于此目录下。
  • /mnt: /media:光盘默认挂载点,通常光盘挂载于 /mnt/cdrom 下,也不一定,可以选择任意位置进行挂载。
  • /opt:给主机额外安装软件所摆放的目录。
  • /proc:此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的目录有 /proc/cpuinfo、/proc/interrupts、/proc/dma、/proc/ioports、/proc/net1表示 第2列表示小时0~23(0表示0点) 第3列表示日期1~31 第4列表示月份1~12 第5列标识号星期0~6(0表示星期天) 第6列要运行的命令

    • 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。command表示要执行的命令。
    • 当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,以此类推
    • 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,以此类推
    • 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,以此类推
    • 当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,以此类推

    在 12 月内, 每天的早上 6 点到 12 点,每隔 3 个小时 0 分钟执行一次 /usr/bin/backup

    0 6-12/3 * 12 * /usr/bin/backup
    

    周一到周五每天下午 5:00 寄一封信给 alex@domain.name

    0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata
    

    每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分…执行 echo “haha”

    20 0-23/2 * * * echo "haha"
    

    示例1:

    45 4 1,10,22 * * /etc/init.d/smb restart 每月1、10、22日的4 : 45重启smb
    
    10 1 * * 6,0 /etc/init.d/smb restart  每周六、周日的1 : 10重启smb
    
    0,30 18-23 * * * /etc/init.d/smb restart  每天18 : 00至23 : 00之间每隔30分钟重启smb
    
    0 23 * * 6 /etc/init.d/smb restart  每星期六的晚上11 : 00 pm重启smb
    
    * */1 * * * /etc/init.d/smb restart  每一小时重启smb
    
    * 23-7/1 * * * /etc/init.d/smb restart  晚上11点到早上7点之间,每隔一小时重启smb
    

    示例2:

    0 */2 * * * /sbin/service httpd restart  每两个小时重启一次apache 
    
    50 7 * * * /sbin/service sshd start  每天7:50开启ssh服务 
    
    50 22 * * * /sbin/service sshd stop  每天22:50关闭ssh服务 
    
    0 0 1,15 * * fsck /home  每月1号和15号检查/home 磁盘 
    
    1 * * * * /home/bruce/backup  每小时的第一分执行 /home/bruce/backup这个文件 
    
    00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} ;  每周一至周五3点钟,在目录/home中,查找文件名为*.xxx的文件,并删除4天前的文件。
    
    30 6 */10 * * ls  每月的1、11、21、31日是的6:30执行一次ls命令
    

    环境变量问题:

    有时创建了一个crontab,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,这种情况一般是由于在crontab文件中没有配置环境变量引起的。

    所以注意如下3点:

    1)脚本中涉及文件路径时写全局路径;

    2)脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如:

    cat start_cbp.sh
    #!/bin/sh
    source /etc/profile
    export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf
    /usr/local/jboss-4.0.5/bin/run.sh -c mev &
    

    3)当手动执行脚本OK,但是crontab死活不执行时,可以尝试在crontab中直接引入环境变量解决问题。如:

    0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
    
    特殊权限

    linux共12位权限,除了9位基础权限还有3个特殊权限。

    三种特殊的权限 SetUID(suid)

    命令功能: **临时使用命令的属主权限执行该命令。**即如果文件有suid权限时,那么普通用户去执行该文件时,会以该文件的所属用户的身份去执行。

    SetUID(简写suid):会在属主权限位的执行权限上写个s。 如果该属主权限位上有执行权限,则会在属主权限位的执行权限上写个s(小写); 如果该属主权限位上没有执行权限,则会在属主权限位的执行权限上写个S(大写)。

    suid数字权限是4000,设置方法:

    方式1:
    [root@centos7 ~]# chmod u+s filename
    方式2:
    [root@centos7 ~]# chmod 4755 filename
    

    查看passwd命令的权限

    `[root@localhost ftl]``# ll /usr/bin/passwd ` `问题: ``passwd``文件的属组是root,表示只有root用户可以访问的文件,为什么普通用户依然可以使用该命令更改自己的密码?``答案:当普通用户[omd]使用``passwd``命令的时候,系统看到``passwd``命令文件的属性有大写s后,表示这个命令的属主权限被omd用户获得,也就是omd用户获得文件``/etc/shadow``的root的rwx权限`
    

    由于passwd具有s权限,普通用户使用该命令的时候,就会以该命令的属主身份root执行该命令,于是能够顺利修改普通用户不具备修改权限的/etc/shadow文件。

    希望普通用户user1可以删除某个自己没有权限删除的文件的操作方法:

    • sudo给user1授权rm权限
    • rm设置suid
    • 修改被删除文件上级目录的权限

    SetUID(简称suid)总结:

    1. 让普通用户对可执行的二进制文件,临时拥有二进制文件的属主权限;
    2. 如果设置的二进制文件没有执行权限,那么suid的权限显示就是S(大写字母S);
    3. 特殊权限suid仅对二进制可执行程序有效,其他文件或目录则无效。
    4. suid极其危险,如果给vim或者rm命令设置了setUID,那么任何文件都能编辑或者删除了,相当于有root权限了。
    setGID(sgid)

    **命令功能:**使用sgid可以使得多个用户之间共享一个目录的所有文件变得简单。当某个目录设置了sgid后,在该目录中新建的文件不在是创建该文件的默认所属组。

    如果该属组权限位上有执行权限,则会在属组主权限位的执行权限上写个s(小写字母); 如果该属组权限位上没有执行权限,则会在属组主权限位的执行权限上写个S(大写字母S)。

    write命令的权限:

    [root@VM_0_9_centos ~]# ll /bin/write 
    -rwxr-sr-x 1 root tty 19544 Aug  9 11:10 /bin/write
    

    sgid数字权限是2000,设置方法:

    方式1:
    [root@VM_0_9_centos ~]# chmod 2755 test/
    方式2:
    [root@VM_0_9_centos ~]# chmod g+s test/
    
    [root@VM_0_9_centos ~]# ll -d test/
    drwxr-sr-x 2 root root 4096 Nov 22 21:02 test/
    

    在设置SetGID的文件夹创建文件的属组是父目录的属组:

    [root@VM_0_9_centos ~]# cd test/
    [root@VM_0_9_centos test]# su aaa
    [aaa@VM_0_9_centos test]$ touch bbb
    [aaa@VM_0_9_centos test]$ ll
    -rw-rw-r-- 1 aaa  root 0 Nov 22 21:14 bbb
    
    sticky(sbit)粘滞位

    **命令功能:**粘滞位,只对目录有效,对某目录设置粘滞位后,普通用户就算有w权限也只能删除该目录下自己建立的文件,而不能删除其他用户建立的文件。

    如果该其他用户权限位上有执行权限,则会在其他用户权限位的执行权限上写个t(小写); 如果该其它用户权限位上没有执行权限,则会在其他用户权限位的执行权限上写个T(大写)。

    系统中存在的/tmp目录是经典的粘滞位目录,谁都有写权限,因此安全成问题,常常是木马第一手跳板。

    [aaa@VM_0_9_centos ~]$ ll -d /tmp/ 
    drwxrwxrwt. 9 root root 4096 Nov 22 21:15 /tmp/
    

    sbit数字权限是1000,设置方法:

    方法1:
    [root@VM_0_9_centos ~]# chmod 1755 test/
    方法2:
    [root@VM_0_9_centos ~]# chmod o+t test/ 
    查看权限:
    [root@VM_0_9_centos ~]# ll -d test/    
    drwxr-xr-t 2 root root 4096 Nov 22 21:15 test/
    
    chattr权限

    chattr概述:凌驾于r、w、x、suid、sgid之上的权限。

    lsattr:查看特殊权限
    [root@VM_0_9_centos ~]# lsattr /etc/passwd
    -------------e-- /etc/passwd
    
    chattr:设置特殊权限
    权限说明
    -i锁定文件,不能编辑,不能修改,不能删除,不能移动,可以执行
    -a仅可以追加文件,不能编辑,不能删除,不能移动,可以执行

    防止系统中某个关键文件被修改:

    [root@VM_0_9_centos ~]# chattr +i /etc/fstab
    [root@VM_0_9_centos ~]# lsattr /etc/fstab   
    ----i--------e-- /etc/fstab
    

    让某个文件只能往里面追加内容,不能删除,一些日志文件适用于这种操作:

    [root@VM_0_9_centos ~]# chattr +a user_act.log
    [root@VM_0_9_centos ~]# lsattr user_act.log 
    -----a-------e-- user_act.log
    
    掩码umask umask的作用

    umask值用于设置用户在创建文件时的默认权限,当我们在系统中创建目录或文件时,目录或文件所具有的默认权限就是由umask值决定的。

    对于root用户,系统默认的umask值是0022;对于普通用户,系统默认的umask值是0002。执行umask命令可以查看当前用户的umask值。

    [root@VM_0_9_centos ~]# umask
    0022
    
    umask是如何改变新文件的权限

    umask值一共有4组数字,其中第1组数字用于定义特殊权限,一般不予考虑,与一般权限有关的是后3组数字。

    默认情况下,对于目录,用户所能拥有的最大权限是777;对于文件,用户所能拥有的最大权限是目录的最大权限去掉执行权限,即666。因为x执行权限对于目录是必须的,没有执行权限就无法进入目录,而对于文件则不必默认赋予x执行权限。

    对于root用户,他的umask值是022。当root用户创建目录时,默认的权限就是用最大权限777去掉相应位置的umask值权限,即对于所有者不必去掉任何权限,对于所属组要去掉w权限,对于其他用户也要去掉w权限,所以目录的默认权限就是755;当root用户创建文件时,默认的权限则是用最大权限666去掉相应位置的umask值,即文件的默认权限是644。

    通过umask命令可以修改umask值,比如将umask值设为0077。

    [root@VM_0_9_centos ~]# umask 0077
    [root@VM_0_9_centos ~]# umask
    0077
    
    永久修改umask

    umask命令只能临时修改umask值,系统重启之后umask将还原成默认值。如果要永久修改umask值,可修改/etc/bashrc或/etc/profile文件。

    例如要将默认umask值设置为027,那么可以在文件中增加一行umask 027。

    linux软件安装 Ubuntu软件安装与卸载 更新Ubuntu软件下载地址

    开源软件镜像站 :https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/

    Ubuntu 的软件源配置文件是 /etc/apt/sources.list。将系统自带的该文件做个备份,将该文件替换为下面内容,即可使用 TUNA 的软件源镜像。

    ubuntu版本: 16.04 LTS

    # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
    deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
    deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
    deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
    deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
    
    # 预发布软件源,不建议启用
    # deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
    # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
    

    然后

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
    

    再sudo vim /etc/apt/sources.list修改为以上内容

    Ubuntu软件操作的相关命令
    sudo apt-get update  更新源
    sudo apt-get install package 安装包
    sudo apt-get remove package 删除包
    sudo apt-cache search package 搜索软件包
    sudo apt-cache show package  获取包的相关信息,如说明、大小、版本等
    sudo apt-get install package --reinstall   重新安装包
    sudo apt-get -f install   修复安装
    sudo apt-get remove package --purge 删除包,包括配置文件等
    sudo apt-get build-dep package 安装相关的编译环境
    sudo apt-get upgrade 更新已安装的包
    sudo apt-get dist-upgrade 升级系统
    sudo apt-cache depends package 了解使用该包依赖那些包
    sudo apt-cache rdepends package 查看该包被哪些包依赖
    sudo apt-get source package  下载该包的源代码
    sudo apt-get clean && sudo apt-get autoclean 清理无用的包
    sudo apt-get check 检查是否有损坏的依赖
    
    yum安装命令

    yum( Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器。

    基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。

    yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。

    更新国内yum源

    网易(163)yum源是国内最好的yum源之一 ,无论是速度还是软件版本,都非常的不错。

    将yum源设置为163 yum,可以提升软件包安装和更新的速度,同时避免一些常见软件版本无法找到。

    首先备份/etc/yum.repos.d/CentOS-Base.repo

    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    

    下载对应版本 repo 文件, 放入 /etc/yum.repos.d/

    • CentOS5 :http://mirrors.163.com/.help/CentOS5-Base-163.repo
    • CentOS6 :http://mirrors.163.com/.help/CentOS6-Base-163.repo
    • CentOS7 :http://mirrors.163.com/.help/CentOS7-Base-163.repo
    wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
    mv CentOS7-Base-163.repo /etc/yum.repos.d/CentOS-Base.repo
    

    运行以下命令生成缓存

    yum clean all
    yum makecache
    

    除了网易之外,国内还有其他不错的 yum 源,比如中科大和搜狐。

    中科大的 yum 源,安装方法查看:https://lug.ustc.edu.cn/wiki/mirrors/help/centos

    sohu 的 yum 源安装方法查看: http://mirrors.sohu.com/help/centos.html

    yum常用命令

    yum 语法:

    yum [options] [command] [package ...]
    

    选项:

    • **options:**可选,选项包括-h(帮助),-y(当安装过程提示选择全部为"yes"),-q(不显示安装的过程)等等。
    • **command:**要进行的操作。
    • **package:**操作的对象。

    实例:

    • 列出所有可更新的软件清单命令:yum check-update
    • 更新所有软件命令:yum update
    • 仅安装指定的软件命令:yum install
    • 仅更新指定的软件命令:yum update
    • 显示包信息:yum info
    • 列出所有可安裝的软件清单命令:yum list
    • 删除软件包命令:yum remove
    • 查找软件包 命令:yum search
    • 清除缓存命令:
      • yum clean packages: 清除缓存目录下的软件包
      • yum clean headers: 清除缓存目录下的 headers
      • yum clean oldheaders: 清除缓存目录下旧的 headers
      • yum clean, yum clean all (= yum clean packages; yum clean oldheaders) :清除缓存目录下的软件包及旧的headers
    yum在线安装MySQL5.7

    Step1: 检测系统是否自带安装mysql

    yum list installed | grep mysql
    

    Step2: 删除系统自带的mysql及其依赖

    yum -y remove mysql-libs.x86_64
    

    Step3: 给CentOS添加rpm源,并且选择较新的源

    wget dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
    yum localinstall mysql-community-release-el7-5.noarch.rpm
    yum repolist all | grep mysql
    yum-config-manager --disable mysql55-community
    yum-config-manager --disable mysql56-community
    yum-config-manager --enable mysql57-community-dmr
    yum repolist enabled | grep mysql
    

    Step4:安装mysql 服务器

    yum install mysql-community-server
    

    Step5: 启动mysql

    service mysqld start
    

    grep “password” /var/log/mysqld.log(查看临时密码)

    SET PASSWORD = PASSWORd('your new password');
    ALTER USER 'root'@'localhost' PASSWORD EXPIRE NEVER;
    flush privileges;
    

    默认的要求必须的设置格式:
    包含数字、小写或大写字母以及特殊字符

    默认的要求必须的设置格式:
    包含数字、小写或大写字母以及特殊字符

    如果不想复杂,可以使用以下方式

    set global validate_password_policy=0;
    set global validate_password_length=1;
    

    Step6: 查看mysql是否自启动,并且设置开启自启动

    # chkconfig --list | grep mysqld
    # chkconfig mysqld on
    

    Step7: mysql安全设置

    mysql_secure_installation
    
    rpm

    RPM是Red Hat公司随Redhat Linux推出了一个软件包管理器,通过它能够更加轻松容易地实现软件的安装。

    常见用法:

    • rpm -ivh 安装软件
    • rpm -e 卸载安装
    • rpm -qi 显示软件安装信息
    • rpm -qa | grep xxx 查询软件是否安装(包括相关依赖)
    • rpm -Uvh 升级一个rpm

    具体参数详解:
    -i, --install 安装包
    -v, --verbose 列出更多详细信息,安装进度
    -h, --hash 安装时列出hash标记 (与 -v连用)
    -e, --erase 卸载安装包
    -U, --upgrade=+ 升级包
    –replacepkge 无论软件包是否已被安装,都强行安装软件包
    –test 安装测试,并不实际安装
    –nodeps 忽略软件包的依赖关系强行安装
    –force 忽略软件包及文件的冲突
    -q,–query:
    -a, --all 查询/校验所有的安装包
    -p, --package 查询/校验一个安装文件
    -l, --list 列出安装文件
    -d, --docfiles 列出所有文档文件
    -f, --file 查询/校验安装包中所包含的文件

    安装软件:

    # rpm -hvi dejagnu-1.4.2-10.noarch.rpm 
    警告:dejagnu-1.4.2-10.noarch.rpm: V3 DSA 签名:NOKEY, key ID db42a60e
    准备...           
    ########################################### [100%]
    

    显示软件安装信息:

    # rpm -qi dejagnu-1.4.2-10.noarch.rpm
    
    【第1次更新 教程、类似命令关联】
    
    Linux的基本配置

    1.修改主机名

    vi /etc/sysconfig/network
    NETWORKING=yes
    HOSTNAME=hadoop1
    

    2.修改ip地址

    vi /etc/sysconfig/network-scripts/ifcfg-eth0
    DEVICE=eth0
    TYPE=Ethernet
    ONBOOT=yes
    BOOTPROTO=static
    IPADDR=192.168.100.101
    NETMASK=255.255.255.0
    
    service network restart
    

    3.修改ip地址和主机名的映射关系

    vi /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.100.101 hadoop1
    

    4.关闭iptables并设置其开机启动/不启动

    service iptables stop
    chkconfig iptables on
    chkconfig iptables off
    
    安装JDK
    1.上传jdk-7u45-linux-x64.tar.gz到Linux上
    2.解压jdk到/usr/local目录
    tar -zxvf jdk-7u45-linux-x64.tar.gz -C /usr/local/
    3.设置环境变量,在/etc/profile文件最后追加相关内容(技巧r:!pwd)
    vi /etc/profile
    export JAVA_HOME=/usr/local/jdk1.7.0_45
    export PATH=$PATH:$JAVA_HOME/bin
    4.刷新环境变量
    source /etc/profile
    5.测试java命令是否可用
    java -version
    
    制作本地YUM源

    上传CentOS-6.7-x86_64-bin-DVD1.iso到服务器

    将CentOS-6.7-x86_64-bin-DVD1.iso镜像挂载到某个目录:

    mkdir /var/iso
    mount -o loop CentOS-6.7-x86_64-bin-DVD1.iso /var/iso
    

    安装并启动Apache服务器:

    yum install -y httpd
    service httpd start
    

    使用浏览器访问http://192.168.100.101(如果访问不通,检查防火墙是否开启了80端口或关闭防火墙)

    将YUM源配置到httpd中:

    cp -r /var/iso/ /var/www/html/CentOS-6.7
    umount /var/iso
    

    在浏览器中访问http://192.168.100.101/CentOS-6.7/

    配置使用YUM源:

    备份原有的YUM源的配置文件

    cd /etc/yum.repos.d/
    rename .repo .repo.bak *
    

    修改YUM源配置文件

    vi CentOS-Local.repo
    [base]
    name=CentOS-Local
    baseurl=http://192.168.100.101/CentOS-6.7
    gpgcheck=1
    enabled=1   #很重要,1才启用
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
    

    重建yum缓存

    #清除yum缓存文件,重新新建
    yum clean all && yum makecache
    #列出可用的YUM源
    yum repolist
    

    rpm包生成yum源目录

    如果已经下载好了rpm包,可以自行制作一个yum源(yum仓库)。将下载的rpm包上传到centos服务器上(比如/data/rpm目录下),然后进入存放rpm包的目录,执行以下命令:

    # cd /data/rpm
    # createrepo .
    

    这样,rpm包存放的目录就可以作为yum源目录使用。
    如果提示找不到createrepo命令,可以使用yum install createrepo安装该程序。

    Shell编程

    这里说的Shell 脚本(shell script),是在Linux 环境下运行的脚本程序

    Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

    Linux 的 Shell 种类众多,常见的有:

    • Bourne Shell(/usr/bin/sh或/bin/sh)
    • Bourne Again Shell(/bin/bash)
    • C Shell(/usr/bin/csh)
    • K Shell(/usr/bin/ksh)
    • Shell for Root(/sbin/sh)
    • ……

    Bash是大多数Linux 系统默认的 Shell,本文也仅关注Bash Shell。

    在一般情况下,并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。

    #! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

    入门 运行Shell脚本

    编写shell脚本:

    vi test.sh
    
    #!/bin/bash
    echo "Hello World !"
    

    #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

    echo 命令用于向窗口输出文本。

    运行 Shell 脚本有两种方法:

    1、作为可执行程序

    chmod +x ./test.sh  #使脚本具有执行权限
    ./test.sh  #执行脚本
    

    默认情况下,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样。

    除非将当前目录.加入到PATH环境变量中,配置方法:

    sudo vi /etc/profile
    加入一行
    export PATH=$PATH:.
    保存之后,执行
    source /etc/profile
    

    2、作为解释器参数

    直接运行解释器,其参数就是 shell 脚本的文件名:

    /bin/sh test.sh
    

    这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

    编写一个快捷创建shell脚本的命令
    #!/bin/bash
    if test -z $1;then
      newfile="./script_`date +%m%d_%s`"
    else
      newfile=$1
    fi
    echo $newfile
    if  ! grep "^#!" $newfile &>/dev/null; then
    cat >> $newfile << EOF
    #!/bin/bash
    # Author:
    # Date & Time: `date +"%F %T"`
    #Description:
    EOF
    fi
    vim +5 $newfile
    chmod +x $newfile
    

    将以上内容编写好之后保存为shell文件,然后执行

    chmod u+x shell
    sudo mv shell /usr/bin/
    
    echo命令

    Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。命令格式:

    echo string
    

    显示普通字符串:

    echo "It is a test"
    

    这里的双引号完全可以省略,以下命令与上面实例效果一致:

    echo It is a test
    

    显示转义字符:

    echo ""It is a test""
    

    结果将是:

    "It is a test"
    

    同样,双引号也可以省略

    read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量

    #!/bin/sh
    read name 
    echo "$name It is a test"
    

    以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:

    [root@www ~]# sh test.sh
    OK                     #标准输入
    OK It is a test        #输出
    
    显示换行
    echo -e "OK! n" # -e 开启转义
    echo "It is a test"
    

    输出结果:

    OK!
    
    It is a test
    
    显示不换行
    #!/bin/sh
    echo -e "OK! c" # -e 开启转义 c 不换行
    echo "It is a test"
    

    输出结果:

    OK! It is a test
    
    printf 命令

    printf 命令的语法:

    printf  format-string  [arguments...]
    

    参数说明:

    • format-string: 为格式控制字符串
    • arguments: 为参数列表。

    实例如下:

    #!/bin/bash
     
    printf "%-10s %-8s %-4sn" 姓名 性别 体重kg  
    printf "%-10s %-8s %-4.2fn" 郭靖 男 66.1234 
    printf "%-10s %-8s %-4.2fn" 杨过 男 48.6543 
    printf "%-10s %-8s %-4.2fn" 郭芙 女 47.9876 
    

    执行脚本,输出结果如下所示:

    姓名     性别   体重kg
    郭靖     男      66.12
    杨过     男      48.65
    郭芙     女      47.99
    
    • %s %c %d %f都是格式替代符
    • %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
    • %-4.2f 指格式化为小数,其中.2指保留2位小数。

    printf的转义序列:

    序列说明
    a警告字符,通常为ASCII的BEL字符
    b后退
    c抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
    f换页(formfeed)
    n换行
    r回车(Carriage return)
    t水平制表符
    v垂直制表符
    一个字面上的反斜杠字符
    ddd表示1到3位数八进制值的字符。仅在格式字符串中有效
    ddd表示1到3位的八进制值字符

    例子:

    python@ubuntu:~/test$ printf "a string, no processing:<%s>n" "AnB"
    a string, no processing:
    python@ubuntu:~/test$ printf "a string, no processing:<%b>n" "AnB"
    a string, no processing:
    python@ubuntu:~/test$ printf "www.runoob.com a"
    www.runoob.com python@ubuntu:~/test$ 
    
    Shell 注释

    以 # 开头的行就是注释,会被解释器忽略:

    #--------------------------------------------
    # 这是一个注释
    # author:菜鸟教程
    # site:www.taobao.com
    # slogan:学的不仅是技术,更是梦想!
    #--------------------------------------------
    ##### 用户配置区 开始 #####
    #
    #
    # 这里可以添加脚本描述信息
    # 
    #
    ##### 用户配置区 结束  #####
    

    多行注释还可以使用以下格式:

    :< 
    

    EOF 也可以使用其他符号:

    :<<'
    注释内容...
    注释内容...
    注释内容...
    '
    
    :< 
    Shell变量 
    定义变量 
    
    your_name="taobao.com"
    

    变量名的命名须遵循如下规则:

    • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
    • 中间不能有空格,可以使用下划线(_)。
    • 不能使用标点符号。
    • 不能使用bash里的关键字(可用help命令查看保留关键字)。
    使用变量

    在变量名前面加美元符号即可,如:

    your_name="qinjx"
    echo $your_name
    echo ${your_name}
    

    加花括号可以帮助解释器识别变量的边界,比如:

    for skill in Ada Coffe Action Java; do
        echo "I am good at ${skill}Script"
    done
    
    只读变量

    使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

    下面的例子尝试更改只读变量,结果报错:

    python@ubuntu:~/shell$ myUrl="http://www.google.com"
    python@ubuntu:~/shell$ readonly myUrl
    python@ubuntu:~/shell$ myUrl="http://www.baidu.com"
    -bash: myUrl: 只读变量
    
    删除变量

    使用 unset 命令可以删除变量,但不能删除只读变量:

    #!/bin/sh
    myUrl="http://www.baidu.com"
    unset myUrl
    echo $myUrl
    
    变量类型

    运行shell时,会同时存在三种变量:

    • 1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
    • 2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
    • 3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
    Shell 函数

    shell中函数的定义格式如下:

    [ function ] funname [()]
    {
        action;
        [return int;]
    }
    

    说明:

    • 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
    • 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

    示例:

    #!/bin/bash
    
    funWithReturn(){
        echo "这个函数会对输入的两个数字进行相加运算..."
        echo "输入第一个数字: "
        read aNum
        echo "输入第二个数字: "
        read anotherNum
        echo "两个数字分别为 $aNum 和 $anotherNum !"
        return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"
    

    输出,类似下面:

    这个函数会对输入的两个数字进行相加运算...
    输入第一个数字: 
    1
    输入第二个数字: 
    2
    两个数字分别为 1 和 2 !
    输入的两个数字之和为 3 !
    

    函数返回值在调用该函数后通过 $? 来获得。

    注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

    在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…

    带参数的函数示例:

    #!/bin/bash
    
    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    

    输出结果:

    第一个参数为 1 !
    第二个参数为 2 !
    第十个参数为 10 !
    第十个参数为 34 !
    第十一个参数为 73 !
    参数总数有 11 个!
    作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
    

    当n>=10时,需要使用${n}来获取参数。

    另外,还有几个特殊字符用来处理参数:

    参数处理说明
    $#传递到脚本的参数个数
    $*以一个单字符串显示所有向脚本传递的参数
    $$脚本运行的当前进程ID号
    $!后台运行的最后一个进程的ID号
    $@与$*相同,但是使用时加引号,并在引号中返回每个参数。
    $-显示Shell使用的当前选项,与set命令功能相同。
    $?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
    文件包含

    Shell 文件包含的语法格式如下:

    . filename   # 注意点号(.)和文件名中间有一空格
    或
    source filename
    

    实例

    创建两个 shell 脚本文件。

    test1.sh 代码如下:

    #!/bin/bash
    
    url="http://www.baidu.com"
    

    test2.sh 代码如下:

    #!/bin/bash
    
    #使用 . 号来引用test1.sh 文件
    . ./test1.sh
    # 或者使用以下包含文件代码
    # source ./test1.sh
    
    echo "url地址:$url"
    

    接下来,我们为 test2.sh 添加可执行权限并执行:

    $ chmod +x test2.sh 
    $ ./test2.sh 
    url地址:http://www.baidu.com
    

    **注:**被包含的文件 test1.sh 不需要可执行权限。

    shell数据类型 字符串

    字符串可以用单引号,也可以用双引号,也可以不用引号。

    单引号:

    str='this is a string'
    

    单引号字符串的限制:

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

    双引号:

    your_name='taobao'
    str="Hello, I know you are "$your_name"! n"
    echo -e $str
    

    输出结果为:

    Hello, I know you are "taobao"! 
    

    双引号的优点:

    • 双引号里可以有变量
    • 双引号里可以出现转义字符

    拼接字符串:

    your_name="taobao"
    # 使用双引号拼接
    greeting="hello, "$your_name" !"
    greeting_1="hello, ${your_name} !"
    echo $greeting  $greeting_1
    # 使用单引号拼接
    greeting_2='hello, '$your_name' !'
    greeting_3='hello, ${your_name} !'
    echo $greeting_2  $greeting_3
    

    输出结果为:

    hello, taobao ! hello, taobao !
    hello, taobao ! hello, ${your_name} !
    

    获取字符串长度${#s}

    string="abcd"
    echo ${#string} #输出 4
    

    截取字符串${s:n1:n2}

    以下实例从字符串第 2 个字符开始截取 4 个字符:

    string="taobao is a great site"
    echo ${string:1:4} # 输出 unoo
    

    查找字符出现的位置expr index

    查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

    string="taobao is a great site"
    echo `expr index "$string" io`  # 输出 3
    

    注意: 以上脚本中 ` 是反引号,而不是单引号 '。

    数组

    bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

    数组元素的下标由 0 开始编号。

    定义数组

    在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:

    array_name=(value0 value1 value2 value3)
    

    或者

    array_name=(
    value0
    value1
    value2
    value3
    )
    

    或单独定义数组的各个分量:

    array_name[0]=value0
    array_name[1]=value1
    array_name[n]=valuen
    

    可以不使用连续的下标,而且下标的范围没有限制。

    读取数组

    读取数组元素值的一般格式是:

    valuen=${array_name[n]}
    

    例子:

    #!/bin/bash
    
    my_array=(A B "C" D)
    
    echo "第一个元素为: ${my_array[0]}"
    echo "第二个元素为: ${my_array[1]}"
    echo "第三个元素为: ${my_array[2]}"
    echo "第四个元素为: ${my_array[3]}"
    

    执行脚本,输出结果如下所示:

    $ chmod +x test.sh 
    $ ./test.sh
    第一个元素为: A
    第二个元素为: B
    第三个元素为: C
    第四个元素为: D
    

    使用 @或* 符号可以获取数组中的所有元素,例如:

    echo ${array_name[@]}
    

    例子:

    #!/bin/bash
    
    my_array[0]=A
    my_array[1]=B
    my_array[2]=C
    my_array[3]=D
    
    echo "数组的元素为: ${my_array[*]}"
    echo "数组的元素为: ${my_array[@]}"
    

    执行脚本,输出结果如下所示:

    $ chmod +x test.sh 
    $ ./test.sh
    数组的元素为: A B C D
    数组的元素为: A B C D
    
    获取数组的长度

    获取数组长度的方法与获取字符串长度的方法相同,例如:

    # 取得数组元素的个数
    length=${#array_name[@]}
    # 或者
    length=${#array_name[*]}
    # 取得数组单个元素的长度
    lengthn=${#array_name[n]}
    

    例子:

    #!/bin/bash
    
    my_array[0]=A
    my_array[1]=B
    my_array[2]=C
    my_array[3]=D
    
    echo "数组元素个数为: ${#my_array[*]}"
    echo "数组元素个数为: ${#my_array[@]}"
    

    执行脚本,输出结果如下所示:

    $ chmod +x test.sh 
    $ ./test.sh
    数组元素个数为: 4
    数组元素个数为: 4
    
    Shell传递参数

    执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。

    n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……

    $0 为执行的文件名

    test.sh文件内容如下:

    vi test.sh
    #!/bin/bash
    
    echo "Shell 传递参数实例!";
    echo "执行的文件名:$0";
    echo "第一个参数为:$1";
    echo "第二个参数为:$2";
    echo "第三个参数为:$3";
    

    运行结果:

    python@ubuntu:~/test$ sh test.sh 1 2 3
    Shell 传递参数实例!
    执行的文件名:test.sh
    第一个参数为:1
    第二个参数为:2
    第三个参数为:3
    

    参数获取:

    参数处理说明
    $#传递到脚本的参数个数
    $*传递的参数作为一个字符串显示
    $$脚本运行的当前进程ID号
    $!后台运行的最后一个进程的ID号
    $@与$*相同,但是使用时加引号
    $?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
    #!/bin/bash
    
    echo "参数个数为:$#";
    echo "$*传递的参数作为一个字符串显示:$*";
    echo "$@传递的参数作为一个字符串显示:$@";
    echo "脚本运行的当前进程ID号:$$";
    echo "后台运行的最后一个进程的ID号:$!";
    echo "$?"
    

    执行脚本,输出结果如下所示:

    python@ubuntu:~/test$ ./test.sh 1 2 3
    参数个数为:3
    1 2 3传递的参数作为一个字符串显示:1 2 3
    1 2 3传递的参数作为一个字符串显示:1 2 3
    脚本运行的当前进程ID号:5059
    后台运行的最后一个进程的ID号:
    0
    

    $*与$@的区别:

    • 只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则$* 等价于 “1 2 3”(传递了一个参数),而$@等价于 “1” “2” “3”(传递了三个参数)。
    #!/bin/bash
    
    echo "-- "$*" 演示 ---"
    for i in "$*"; do
        echo $i
    done
    
    echo "-- "$@" 演示 ---"
    for i in "$@"; do
        echo $i
    done
    
    echo "-- $* 演示 ---"
    for i in $*; do
        echo $i
    done
    
    echo "-- $@ 演示 ---"
    for i in $@; do
        echo $i
    done
    

    执行脚本,输出结果如下所示:

    python@ubuntu:~/test$ sh test 1 2 3
    -- "$*" 演示 ---
    1 2 3
    -- "$@" 演示 ---
    1
    2
    3
    -- $* 演示 ---
    1
    2
    3
    -- $@ 演示 ---
    1
    2
    3
    
    Shell基本运算符

    Shell 和其他编程语言一样,支持多种运算符,包括:

    • 算数运算符
    • 关系运算符
    • 布尔运算符
    • 字符串运算符
    • 文件测试运算符

    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

    expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

    #!/bin/bash
    
    val=`expr 2 + 2`
    echo "两数之和为 : $val"
    

    执行脚本,输出结果如下所示:

    两数之和为 : 4
    

    两点注意:

    • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
    • 完整的表达式要被 ` ` 包含,这个字符是反引号在 Esc 键下边。
    算术运算符

    下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

    运算符说明举例
    +加法expr $a + $b 结果为 30。
    -减法expr $a - $b 结果为 -10。
    *乘法expr $a * $b 结果为 200。
    /除法expr $b / $a 结果为 2。
    %取余expr $b % $a 结果为 0。
    =赋值a=$b 将把变量 b 的值赋给 a。
    ==相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
    !=不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。

    算术运算符实例如下:

    #!/bin/bash
    
    a=10
    b=20
    
    val=`expr $a + $b`
    echo "a + b : $val"
    
    val=`expr $a - $b`
    echo "a - b : $val"
    
    val=`expr $a * $b`
    echo "a * b : $val"
    
    val=`expr $b / $a`
    echo "b / a : $val"
    
    val=`expr $b % $a`
    echo "b % a : $val"
    
    if [ $a == $b ]
    then
       echo "a 等于 b"
    fi
    if [ $a != $b ]
    then
       echo "a 不等于 b"
    fi
    

    执行脚本,输出结果如下所示:

    a + b : 30
    a - b : -10
    a * b : 200
    b / a : 2
    b % a : 0
    a 不等于 b
    

    注意:

    • 乘号(*)前边必须加反斜杠才能实现乘法运算;
    • if…then…fi 是条件语句,后续将会讲解。
    • 在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 “*” 不需要转义符号 。
    let varName=算术表达式
    varName=$[算术表达式]
    varName=$((算术表达式))
    
    关系运算符

    关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

    下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

    运算符说明举例
    -eq检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 false。
    -ne检测两个数是否不相等,不相等返回 true。[ $a -ne $b ] 返回 true。
    -gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
    -lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
    -ge检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ]返回 false。
    -le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。

    关系运算符实例如下:

    #!/bin/bash
    
    a=10
    b=20
    
    if [ $a -eq $b ]
    then
       echo "$a -eq $b : a 等于 b"
    else
       echo "$a -eq $b: a 不等于 b"
    fi
    if [ $a -ne $b ]
    then
       echo "$a -ne $b: a 不等于 b"
    else
       echo "$a -ne $b : a 等于 b"
    fi
    if [ $a -gt $b ]
    then
       echo "$a -gt $b: a 大于 b"
    else
       echo "$a -gt $b: a 不大于 b"
    fi
    if [ $a -lt $b ]
    then
       echo "$a -lt $b: a 小于 b"
    else
       echo "$a -lt $b: a 不小于 b"
    fi
    if [ $a -ge $b ]
    then
       echo "$a -ge $b: a 大于或等于 b"
    else
       echo "$a -ge $b: a 小于 b"
    fi
    if [ $a -le $b ]
    then
       echo "$a -le $b: a 小于或等于 b"
    else
       echo "$a -le $b: a 大于 b"
    fi
    

    执行脚本,输出结果如下所示:

    10 -eq 20: a 不等于 b
    10 -ne 20: a 不等于 b
    10 -gt 20: a 不大于 b
    10 -lt 20: a 小于 b
    10 -ge 20: a 小于 b
    10 -le 20: a 小于或等于 b
    
    布尔运算符

    下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

    运算符说明举例
    !非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
    -o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
    -a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

    布尔运算符实例如下:

    #!/bin/bash
    
    a=10
    b=20
    
    if [ $a != $b ]
    then
       echo "$a != $b : a 不等于 b"
    else
       echo "$a == $b: a 等于 b"
    fi
    if [ $a -lt 100 -a $b -gt 15 ]
    then
       echo "$a 小于 100 且 $b 大于 15 : 返回 true"
    else
       echo "$a 小于 100 且 $b 大于 15 : 返回 false"
    fi
    if [ $a -lt 100 -o $b -gt 100 ]
    then
       echo "$a 小于 100 或 $b 大于 100 : 返回 true"
    else
       echo "$a 小于 100 或 $b 大于 100 : 返回 false"
    fi
    if [ $a -lt 5 -o $b -gt 100 ]
    then
       echo "$a 小于 5 或 $b 大于 100 : 返回 true"
    else
       echo "$a 小于 5 或 $b 大于 100 : 返回 false"
    fi
    

    执行脚本,输出结果如下所示:

    10 != 20 : a 不等于 b
    10 小于 100 且 20 大于 15 : 返回 true
    10 小于 100 或 20 大于 100 : 返回 true
    10 小于 5 或 20 大于 100 : 返回 false
    
    逻辑运算符

    以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:

    运算符说明举例
    &&逻辑的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false
    ||逻辑的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true

    逻辑运算符实例如下:

    #!/bin/bash
    
    a=10
    b=20
    
    if [[ $a -lt 100 && $b -gt 100 ]]
    then
       echo "返回 true"
    else
       echo "返回 false"
    fi
    
    if [[ $a -lt 100 || $b -gt 100 ]]
    then
       echo "返回 true"
    else
       echo "返回 false"
    fi
    

    执行脚本,输出结果如下所示:

    返回 false
    返回 true
    
    字符串运算符

    下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

    运算符说明举例
    =检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
    !=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
    -z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
    -n检测字符串长度是否为0,不为0返回 true。[ -n "$a" ] 返回 true。
    $检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

    字符串运算符实例如下:

    #!/bin/bash
    
    a="abc"
    b="efg"
    
    if [ $a = $b ]
    then
       echo "$a = $b : a 等于 b"
    else
       echo "$a = $b: a 不等于 b"
    fi
    if [ $a != $b ]
    then
       echo "$a != $b : a 不等于 b"
    else
       echo "$a != $b: a 等于 b"
    fi
    if [ -z $a ]
    then
       echo "-z $a : 字符串长度为 0"
    else
       echo "-z $a : 字符串长度不为 0"
    fi
    if [ -n "$a" ]
    then
       echo "-n $a : 字符串长度不为 0"
    else
       echo "-n $a : 字符串长度为 0"
    fi
    if [ $a ]
    then
       echo "$a : 字符串不为空"
    else
       echo "$a : 字符串为空"
    fi
    

    执行脚本,输出结果如下所示:

    abc = efg: a 不等于 b
    abc != efg : a 不等于 b
    -z abc : 字符串长度不为 0
    -n abc : 字符串长度不为 0
    abc : 字符串不为空
    
    文件测试运算符

    文件测试运算符用于检测 Unix 文件的各种属性。

    属性检测描述如下:

    操作符说明举例
    -b file检测文件是否是块设备文件,如果是,则返回 true。[ -b $file ] 返回 false。
    -c file检测文件是否是字符设备文件,如果是,则返回 true。[ -c $file ] 返回 false。
    -d file检测文件是否是目录,如果是,则返回 true。[ -d $file ] 返回 false。
    -f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。[ -f $file ] 返回 true。
    -g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g $file ] 返回 false。
    -k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。[ -k $file ] 返回 false。
    -p file检测文件是否是有名管道,如果是,则返回 true。[ -p $file ] 返回 false。
    -u file检测文件是否设置了 SUID 位,如果是,则返回 true。[ -u $file ] 返回 false。
    -r file检测文件是否可读,如果是,则返回 true。[ -r $file ] 返回 true。
    -w file检测文件是否可写,如果是,则返回 true。[ -w $file ] 返回 true。
    -x file检测文件是否可执行,如果是,则返回 true。[ -x $file ] 返回 true。
    -s file检测文件是否为空(文件大小是否大于0),不为空返回 true。[ -s $file ] 返回 true。
    -e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

    其他检查符:

    • -S: 判断某文件是否 socket。
    • -L: 检测文件是否存在并且是一个符号链接。

    变量 file 表示文件 /var/www/runoob/test.sh,它的大小为 100 字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性:

    #!/bin/bash
    
    file="/var/www/runoob/test.sh"
    if [ -r $file ]
    then
       echo "文件可读"
    else
       echo "文件不可读"
    fi
    if [ -w $file ]
    then
       echo "文件可写"
    else
       echo "文件不可写"
    fi
    if [ -x $file ]
    then
       echo "文件可执行"
    else
       echo "文件不可执行"
    fi
    if [ -f $file ]
    then
       echo "文件为普通文件"
    else
       echo "文件为特殊文件"
    fi
    if [ -d $file ]
    then
       echo "文件是个目录"
    else
       echo "文件不是个目录"
    fi
    if [ -s $file ]
    then
       echo "文件不为空"
    else
       echo "文件为空"
    fi
    if [ -e $file ]
    then
       echo "文件存在"
    else
       echo "文件不存在"
    fi
    

    执行脚本,输出结果如下所示:

    文件可读
    文件可写
    文件可执行
    文件为普通文件
    文件不是个目录
    文件不为空
    文件存在
    
    test命令

    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

    数值测试
    参数说明
    -eq等于则为真
    -ne不等于则为真
    -gt大于则为真
    -ge大于等于则为真
    -lt小于则为真
    -le小于等于则为真

    实例演示:

    num1=100
    num2=100
    if test $[num1] -eq $[num2]
    then
        echo '两个数相等!'
    else
        echo '两个数不相等!'
    fi
    

    输出结果:

    两个数相等!
    

    代码中的 [] 执行基本的算数运算,如:

    #!/bin/bash
    
    a=5
    b=6
    
    result=$[a+b] # 注意等号两边不能有空格
    echo "result 为: $result"
    

    结果为:

    result 为: 11
    
    字符串测试
    参数说明
    =等于则为真
    !=不相等则为真
    -z 字符串字符串的长度为零则为真
    -n 字符串字符串的长度不为零则为真

    实例演示:

    num1="ru1noob"
    num2="runoob"
    if test $num1 = $num2
    then
        echo '两个字符串相等!'
    else
        echo '两个字符串不相等!'
    fi
    

    输出结果:

    两个字符串不相等!
    
    文件测试
    参数说明
    -e 文件名如果文件存在则为真
    -r 文件名如果文件存在且可读则为真
    -w 文件名如果文件存在且可写则为真
    -x 文件名如果文件存在且可执行则为真
    -s 文件名如果文件存在且至少有一个字符则为真
    -d 文件名如果文件存在且为目录则为真
    -f 文件名如果文件存在且为普通文件则为真
    -c 文件名如果文件存在且为字符型特殊文件则为真
    -b 文件名如果文件存在且为块特殊文件则为真

    实例演示:

    cd /bin
    if test -e ./bash
    then
        echo '文件已存在!'
    else
        echo '文件不存在!'
    fi
    

    输出结果:

    文件已存在!
    

    另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!“最高,”-a"次之,"-o"最低。例如:

    cd /bin
    if test -e ./notFile -o -e ./bash
    then
        echo '至少有一个文件存在!'
    else
        echo '两个文件都不存在'
    fi
    

    输出结果:

    至少有一个文件存在!
    
    Shell 流程控制 if else判断语句

    if 语句语法格式:

    if condition
    then
        command1 
        command2
        ...
        commandN 
    fi
    

    写成一行(适用于终端命令提示符):

    if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
    

    if else 语法格式:

    if condition
    then
        command1 
        command2
        ...
        commandN
    else
        command
    fi
    

    if else-if else 语法格式:

    if condition1
    then
        command1
    elif condition2 
    then 
        command2
    else
        commandN
    fi
    

    以下实例判断两个变量是否相等:

    a=10
    b=20
    if [ $a == $b ]
    then
       echo "a 等于 b"
    elif [ $a -gt $b ]
    then
       echo "a 大于 b"
    elif [ $a -lt $b ]
    then
       echo "a 小于 b"
    else
       echo "没有符合的条件"
    fi
    

    输出结果:

    a 小于 b
    

    if else语句经常与test命令结合使用,如下所示:

    num1=$[2*3]
    num2=$[1+5]
    if test $[num1] -eq $[num2]
    then
        echo '两个数字相等!'
    else
        echo '两个数字不相等!'
    fi
    

    输出结果:

    两个数字相等!
    
    for循环

    for循环一般格式为:

    for var in item1 item2 ... itemN
    do
        command1
        command2
        ...
        commandN
    done
    

    写成一行:

    for var in item1 item2 ... itemN; do command1; command2… done;
    

    例如,顺序输出当前列表中的数字:

    for loop in 1 2 3 4 5
    do
        echo "The value is: $loop"
    done
    

    输出结果:

    The value is: 1
    The value is: 2
    The value is: 3
    The value is: 4
    The value is: 5
    

    顺序输出字符串中的字符:

    for str in 'This is a string'
    do
        echo $str
    done
    

    输出结果:

    This is a string
    
    while循环

    while循环格式为:

    while condition
    do
        command
    done
    

    示例:

    #!/bin/bash
    int=1
    while(( $int<=5 ))
    do
        echo $int
        let "int++"
    done
    

    运行脚本,输出:

    1
    2
    3
    4
    5
    

    while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按Ctrl-D结束循环。

    echo '按下  退出'
    echo -n '输入你最喜欢的网站名: '
    while read FILM
    do
        echo "是的!$FILM 是一个好网站"
    done
    

    运行脚本,输出类似下面:

    按下  退出
    输入你最喜欢的网站名:淘宝
    是的!淘宝 是一个好网站
    
    无限循环

    无限循环语法格式:

    while :
    do
        command
    done
    

    或者

    while true
    do
        command
    done
    

    或者

    for (( ; ; ))
    
    until 循环

    until 循环执行一系列命令直至条件为 true 时停止。

    until 循环与 while 循环在处理方式上刚好相反。

    一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

    until 语法格式:

    until condition
    do
        command
    done
    

    condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

    以下实例我们使用 until 命令来输出 0 ~ 9 的数字:

    #!/bin/bash
    
    a=0
    
    until [ ! $a -lt 10 ]
    do
       echo $a
       a=`expr $a + 1`
    done
    

    运行结果:

    输出结果为:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    case

    Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:

    case 值 in
    模式1)
        command1
        command2
        ...
        commandN
        ;;
    模式2)
        command1
        command2
        ...
        commandN
        ;;
    esac
    

    下面的脚本提示输入1到4,与每一种模式进行匹配:

    echo '输入 1 到 4 之间的数字:'
    echo '你输入的数字为:'
    read aNum
    case $aNum in
        1)  echo '你选择了 1'
        ;;
        2)  echo '你选择了 2'
        ;;
        3)  echo '你选择了 3'
        ;;
        4)  echo '你选择了 4'
        ;;
        *)  echo '你没有输入 1 到 4 之间的数字'
        ;;
    esac
    

    输入不同的内容,会有不同的结果,例如:

    输入 1 到 4 之间的数字:
    你输入的数字为:
    3
    你选择了 3
    
    跳出循环

    在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。

    break命令允许跳出所有循环(终止执行后面的所有循环)。

    下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。

    #!/bin/bash
    while :
    do
        echo -n "输入 1 到 5 之间的数字:"
        read aNum
        case $aNum in
            1|2|3|4|5) echo "你输入的数字为 $aNum!"
            ;;
            *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
                break
            ;;
        esac
    done
    

    执行以上代码,输出结果为:

    输入 1 到 5 之间的数字:3
    你输入的数字为 3!
    输入 1 到 5 之间的数字:7
    你输入的数字不是 1 到 5 之间的! 游戏结束
    

    continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

    Shell输入/输出重定向

    重定向命令列表如下:

    命令说明
    command > file将输出重定向到 file。
    command < file将输入重定向到 file。
    command >> file将输出以追加的方式重定向到 file。
    n > file将文件描述符为 n 的文件重定向到 file。
    n >> file将文件描述符为 n 的文件以追加的方式重定向到 file。
    n >& m将输出文件 m 和 n 合并。
    n <& m将输入文件 m 和 n 合并。
    << tag将开始标记 tag 和结束标记 tag 之间的内容作为输入。

    需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。


    输出重定向

    重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:

    command1 > file1
    

    上面这个命令执行command1然后将输出的内容存入file1。

    注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。

    输出重定向会覆盖文件内容:

    $ echo "www.baidu.com" > users
    $ cat users
    www.baidu.com
    $
    

    如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:

    $ echo "www.baidu.com" >> users
    $ cat users
    www.baidu.com
    www.baidu.com
    $
    
    输入重定向

    和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

    command1 < file1
    

    这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

    注意:输出重定向是大于号(>),输入重定向是小于号(<)。

    统计 users 文件的行数,执行以下命令:

    python@ubuntu:~/test$ wc -l test 
    4 test
    

    也可以将输入重定向到 users 文件:

    python@ubuntu:~/test$ wc -l  
    

    注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

    同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中:

    command1 < infile > outfile
    
    重定向深入讲解

    一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

    • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
    • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
    • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

    默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

    如果希望 stderr 重定向到 file,可以这样写:

    $ command 2 > file
    

    如果希望 stderr 追加到 file 文件末尾,可以这样写:

    $ command 2 >> file
    

    2 表示标准错误文件(stderr)。

    如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

    $ command > file 2>&1
    或者
    $ command >> file 2>&1
    

    如果希望对 stdin 和 stdout 都重定向,可以这样写:

    $ command < file1 >file2
    

    command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。

    Here Document

    Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。

    它的基本的形式如下:

    command << delimiter
        document
    delimiter
    

    它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

    注意:结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。

    在命令行中通过 wc -l 命令计算 Here Document 的行数:

    $ wc -l << EOF
        欢迎来到
        菜鸟教程
        www.runoob.com
    EOF
    3          # 输出结果为 3 行
    $
    
    /dev/null 文件

    如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

    $ command > /dev/null
    

    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

    如果希望屏蔽 stdout 和 stderr,可以这样写:

    $ command > /dev/null 2>&1
    

    0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

    实例 杨辉三角:
    #!/bin/bash
    
    if (test -z $1) ;then 
     read -p "Input high Int Lines:" high 
    else 
     high=$1 
    fi 
    if (test -z $2) ;then 
     space=4
    else 
     space=$2
    fi
    
    printspace(){
      #空位填充
      for((z=1;z<=$1;z++));do
        echo -n " "
      done
    }
    
    a[0]=1     
    for((i=0;i<=high;i++));do
      #产生当前列数据数组
      for ((j=$i;j>0;j--));do 
        ((a[$j]+=a[$j-1])) 
      done
      printspace $((($high-$i)*$space/2))
      for ((j=0;j<=$i;j++));do
        num=$(($space-${#a[$j]}))
        printspace $(($num/2))
        echo -n ${a[$j]}
        printspace $(($num-$num/2))
      done
      echo ""
    done
    
    sum()&max():
    #!/bin/bash
    
    echo "shell的函数返回值只能为0~255的整数,高位自动丢弃"
    sum(){
     sum=0
     for i in $@
     do
      if test $i -ne $1;then
       echo -n "+"
      fi
      echo -n "$i"
      sum=$(($sum+$i))
     done
     echo "=$sum"
     return $(($sum))
    }
    sum $@
    echo "‘sum()’函数返回值:"$?
    
    max(){
     max=0
     for i in $@;do
      if test $i -ge $max;then
        max=$i
      fi
     done
     echo "参数最大值:$max"
     return $(($max))
    }
    
    max $@
    
    echo "‘max()’函数返回值:"$?
    
    
    99乘法表:
    #!/bin/bash
    
    for i in {1..9};do
     for((j=1;j<=i;j++));do
      echo -en "$i*$j=$(($i*$j))t"
     done
     echo ""
    done
    
    for a in {1..9};do
        for b in {0..9};do
            for c in {0..9};do
                number1=$((a*100+b*10+c))
                number2=$((a**3+b**3+c**3))
                if test $number1 -eq $number2; then
                    echo "Found number $number1"
                fi
            done
        done
    done
    
    文本编辑命令 cut命令
    选项与参数:
    -d  :后面接分隔字符。与 -f 一起使用;
    -f  :依据 -d 的分隔字符将一段信息分割成为数段,用 -f 取出第几段的意思;
    -c  :以字符 (characters) 的单位取出固定字符区间;
    

    cut以行为单位,根据分隔符把行分成若干列,这样就可以指定选取哪些列了。

    cut -d '分隔字符' -f 选取的列数
    echo $PATH|cut -d ':' -f 2  	--选取第2列
    echo $PATH|cut -d ':' -f 3,5  	--选取第3列和第5列
    echo $PATH|cut -d ':' -f 3-5  	--选取第3列到第5列
    echo $PATH|cut -d ':' -f 3-   	--选取第3列到最后1列
    echo $PATH|cut -d ':' -f 1-3,5	--选取第1到第3列还有第5列
    

    只显示/etc/passwd的用户和shell:

    #cat /etc/passwd | cut -d ':' -f 1,7 
    root:/bin/bash
    daemon:/bin/sh
    bin:/bin/sh
    
    sed命令

    sed 可依照脚本的指令来处理、编辑文本文件。

    Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

    语法:

    sed [-e