sh /bin/bash 的区别
ceph@ceph-deploy:~$ ./bb.sh 10.1 10.2 10.3 10.4 10.5 10.6 ceph@ceph-deploy:~$ /bin/bash bb.sh 10.1 10.2 10.3 10.4 10.5 10.6 ceph@ceph-deploy:~$ sh bb.sh 10.{1..6} ceph@ceph-deploy:~$ cat bb.sh #!/bin/bash for i in 10.{1..6} do echo $i done
ceph@ceph-deploy:~$ cat login.sh
#!/bin/bash
export mypass=123456
for i in 10.0.0.{100..105}
do
##3. etcd集o群节点间设置免密登录
echo $i
expect -c "
spawn ssh-copy-id -i /home/ceph/.ssh/id_rsa.pub ceph@$i
expect {
\"*yes/no*\" {send \"yes\r\"; exp_continue}
\"*password*\" {send \"$mypass\r\"; exp_continue}
\"*Password*\" {send \"$mypass\r\";}
}"
done
Shell 中文意思贝壳,寓意类似内核的壳。Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 Shell 脚本(shell script)是一种为 shell 编写的脚本程序。常说的shell通常都是指 shell 脚本,但shell和shell script是两个不同的概念。通常说“shell编程”都是指 shell 脚本编程,不是指开发 shell 自身。 sh(Bourne Shell)是一个早期的重要shell,1978年由史蒂夫·伯恩编写,并同Version 7 Unix一起发布。 bash(Bourne-Again Shell)是一个为GNU计划编写的Unix shell。1987年由布莱恩·福克斯创造。主要目标是与POSIX标准保持一致,同时兼顾对sh的兼容,是各种Linux发行版标准配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash的符号链接。 #!是一个特殊标记,说明这是一个可执行的脚本。除了第一行,其他以#开头的都不再生效,为注释。 #!后面是脚本的解释器程序路径。这个程序可以是shell,程序语言或者其他通用程序,常用的是bash、sh。 sh 跟bash的区别,实际上是bash有没开启POSIX模式的区别。 cat /etc/shells 查看系统可使用的shell类型 sh sh 的全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。 sh 是 UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。 csh sh 之后另一个广为流传的 shell 是由柏克莱大学的 Bill Joy 设计的,这个 shell 的语法有点类似C语言,所以才得名为 C shell ,简称为 csh。 Bill Joy 是一个风云人物,他创立了 BSD 操作系统,开发了 vi 编辑器,还是 Sun 公司的创始人之一。 BSD 是 UNIX 的一个重要分支,后人在此基础上发展出了很多现代的操作系统,最著名的有 FreeBSD、OpenBSD 和 NetBSD,就连 Mac OS X 在很大程度上也基于BSD。 tcsh tcsh 是 csh 的增强版,加入了命令补全功能,提供了更加强大的语法支持。 ash 一个简单的轻量级的 Shell,占用资源少,适合运行于低内存环境,但是与下面讲到的 bash shell 完全兼容。 bash 由 GNU 组织开发,保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。 在现代的 Linux 上,sh 已经被 bash 代替,/bin/sh往往是指向/bin/bash的符号链接。 shell运行的原理 当我们在Linux下输入: ls -al 或者 cd .. 在解释原理之前,我们必须分清楚的是:我们在Linux输入的命令是有区别的,具体来说,分为内部命令(built-in)以及外部命令,向ls,cat,mkdir这些都属于外部命令,而echo,cd,pwd这些都属于内置命令,如何区分这些命令是否是内置,外部命令,可以利用type命令来辨别 输入ls,cd这些内部或者外部的命令有什么区别?具体而言: 像cd,pwd这些内置命令是属于Shell的一部分,当Shell一运行起来就随Shell加载入内存,因此,当我们在命令行上输入这些命令就可以像调用函数一样直接使用,效率非常高。 而如ls,cat这些外部命令却不是如此,当我们在命令行输入cat,当前的Shell会fork一个子进程,然后调用exec载入这个命令的可执行文件,比如bin/cat,因此效率上稍微低了点。 理解了单个命令的运行原理,我们现在探究当编写一个Shell脚本运行的原理,首先需要的说明的是,Shell,和Python一样,都是一门解释性语言,所谓的解释性语言就是不用编译,执行一行解释一行。 在Linux命令输入./ test.sh时(需要加可执行权限)时,我们在这个文本文件开头指定了bash为默认的解释器,因此当前的交互式Shell会fork一个子进程,用bash解释器的代码去替换(也就是exec),而这个文本文件被当作是命令行参数传给这个子bash,等这个子bash执行完就会到我们的交互式bash了。 为了验证我们所说的交互式bash会fork/exec一个子bash来执行命令而非交互式bash,我们做个测试: 1.直接在交互式bash输入: cd .. 2.编写脚本test.sh,然后运行: //其中test.sh内容如下: #!/bin/bash cd .. 在Linux命令行输入 ./test.sh 我们发现同样都是cd ..,为什么执行完脚本当前bash目录不变,因为cd改变的是子shell的工作目录,而非当前shell的命令,这就证明了我们所说的是由子bash执行,而非交互式bash,那么如何交互式bash执行脚本呢,我们可以使用. 或者source命令, source通知当前shell读入路径为filename的文件并依次执行文件中的所有语句。 通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。例如,当我们修改了/etc/profile文件,并想让它立刻生效,而不用重新登录,就可以使用source命令,如“source /etc/profile”。 source命令是bash shell的内置命令。而点命令(即“.”命令)则是source的另一名称。这两个命令都以一个脚本为参数,该脚本将作为当前shell的环境执行,即不会启动一个新的子进程。所有在脚本中设置的变量将成为当前Shell的一部分。 Shell脚本执行的四种方法 bash(或sh) [脚本的相对路径或绝对路径 source(或.) [脚本的相对路径或绝对路径].(点)是等同于source的,最常见的使用是在重新加载环境变量时。 sh < [脚本名称]或者cat [脚本名称] | sh(或bash) 脚本的相对路径或绝对路径,使用该方法,脚本必须拥有执行权限 ./a.sh 方法比较 当shell脚本具有可执行权限时,用sh filename与./filename是没有区别的。./filename是因为当前目录没有在PATH中,所以"."是用来表示当前目录的。 sh filename会重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell是新建的,其改变的变量不会被带回父shell,除非使用export。 source filename读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。 方法举例 新建一个test.sh脚本,内容为:A=1; 修改其可执行权限:chmod +x test.sh; 运行sh test.sh后,echo $A,显示为空,因为A=1并未传回给当前shell; 运行./test.sh后,也是一样的效果; 运行source test.sh 或者 . test.sh,然后echo $A,则会显示1,说明A=1的变量在当前shell中; Shell内置命令 Shell 命令分为外部命令和内置命令: 比较 内置命令 外部命名 定义 Bash Shell 自带的命令 Linux 系统中的应用程序 执行效率 高 低 执行过程 调用当前 Shell 进程的一个函数 触发磁盘 I/O,fork 出一个单独的进程,执行完成后退出 内建命令 定义 内建命令是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件 內建命令及说明 命令 说明 : 扩展参数列表,执行重定向操作 . 读取并执行指定文件中的命令(在当前 shell 环境中) alias 为指定命令定义一个别名 bg 将作业以后台模式运行 bind 将键盘序列绑定到一个 readline 函数或宏 break 退出 for、while、select 或 until 循环 builtin 执行指定的 shell 内建命令 caller 返回活动子函数调用的上下文 cd 将当前目录切换为指定的目录 command 执行指定的命令,无需进行通常的 shell 查找 compgen 为指定单词生成可能的补全匹配 complete 显示指定的单词是如何补全的 compopt 修改指定单词的补全选项 continue 继续执行 for、while、select 或 until 循环的下一次迭代 declare 声明一个变量或变量类型。 dirs 显示当前存储目录的列表 disown 从进程作业表中刪除指定的作业 echo 将指定字符串输出到 STDOUT enable 启用或禁用指定的内建shell命令 eval 将指定的参数拼接成一个命令,然后执行该命令 exec 用指定命令替换 shell 进程 exit 强制 shell 以指定的退出状态码退出 export 设置子 shell 进程可用的变量 fc 从历史记录中选择命令列表 fg 将作业以前台模式运行 getopts 分析指定的位置参数 hash 查找并记住指定命令的全路径名 help 显示帮助文件 history 显示命令历史记录 jobs 列出活动作业 kill 向指定的进程 ID(PID) 发送一个系统信号 let 计算一个数学表达式中的每个参数 local 在函数中创建一个作用域受限的变量 logout 退出登录 shell mapfile 从 STDIN 读取数据行,并将其加入索引数组 popd 从目录栈中删除记录 printf 使用格式化字符串显示文本 pushd 向目录栈添加一个目录 pwd 显示当前工作目录的路径名 read 从 STDIN 读取一行数据并将其赋给一个变量 readarray 从 STDIN 读取数据行并将其放入索引数组 readonly 从 STDIN 读取一行数据并将其赋给一个不可修改的变量 return 强制函数以某个值退出,这个值可以被调用脚本提取 set 设置并显示环境变量的值和 shell 属性 shift 将位置参数依次向下降一个位置 shopt 打开/关闭控制 shell 可选行为的变量值 source 读取并执行指定文件中的命令(在当前 shell 环境中) suspend 暂停 Shell 的执行,直到收到一个 SIGCONT 信号 test 基于指定条件返回退出状态码 0 或 1 times 显示累计的用户和系统时间 trap 如果收到了指定的系统信号,执行指定的命令 type 显示指定的单词如果作为命令将会如何被解释 typeset 声明一个变量或变量类型。 ulimit 为系统用户设置指定的资源的上限 umask 为新建的文件和目录设置默认权限 unalias 刪除指定的别名 unset 刪除指定的环境变量或 shell 属性 wait 等待指定的进程完成,并返回退出状态码 文章知识点与官方知识档案匹配,可进一步学习相关知识 CS入门技能树Linux入门初识Linux28479 人正在系统学习中 ———————————————— 版权声明:本文为CSDN博主「wht1995316」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/wht1995316/article/details/115837282
时来天地皆同力,运去英雄不自由