bash,dash以及执行shell脚本的方法

在Ubuntu 16.04中,由于默认shell是dash,这可能导致基于bash编写的shell脚本执行失败。可以通过修改sh链接指向bash或在脚本中指定bash来解决。本文讨论了为何Ubuntu选择dash(效率高,轻量级)以及如何在保持脚本通用性的前提下,确保基于bash的脚本在dash环境下正确运行。

最近在编译平台SDK时,使用环境是ubuntu16.04,开始通过执行shell脚本配置SDK的编译环境,整个过程刚开始就夭折了,原因是ubuntu的默认shell使用的是dash,而SDK的shell脚本是基于bash而写,自然刚开始执行就失败。
首先,可能会想到把shell脚本中默认指定的shell修改为bash,通常在shell脚本开头都会有如下这样一句指明shell:

#!/bin/sh

这里的sh是一个链接,它实际指向,在ubuntu下默认是指向dash。
通过下面的方法可以修改sh的默认指向,比如通过下面的操作步骤,可以修改sh指向bash:

sudo dpkg-reconfigure dash

执行上述命令后,会弹出一个提示,选择"NO"即可。

上面的方法看起来是没什么问题,那下面说下ubuntu为什么不直接默认指定bash shell呢,原因是dash比bash的效率要高,轻量级,作为一个操作系统,自然效率越高越好。但是一般linux系统还是习惯用bash的比较多,所以大部分shell脚本都会基于bash语法来写,这时可能有人会想到另一种方法,即直接指定shell:

#!/bin/bash

上面这种写法固然是可行,但失去shell脚本的通用性,因为shell脚本可能会执行在不同的shell上,我们知道除了bash,dash这两种shell外,还有很多种ash, ksh等等,所以#!/bin/sh这样的写法似乎是最符合“垮平台”的理念的。

很多程序猿都习惯ubuntu,那怎么在终端控制台(ctrl+alt+t)上,直接执行#!/bin/sh这样的shell脚本呢?其实使用ctrl+alt+t打开的这个控制台,它自己使用的shell其实是bash,另外ubuntu root用户使用的也是bash,可见bash是linux世界里最常用的shell,就连ubuntu也不敢忘本。下面自然想到,让#!/bin/sh在当前shell下面执行就行了,而不用另开一个子shell执行(子shell用的是dash),所以在linux下有个特别的点号,如下:

$. ../xxx.sh

第一个点号指明在当前shell里执行,后面跟一空格,如果没有这个点号,$…/xxx.sh将会另开一个子shell执行脚本,那样就使用ubuntu默认的dash去执行 。

ubuntu下字符终端ctrl+alt+F1-6,有6个字符终端,另外F7是我们通常见到的图形界面。它们所用的shell没有什么区别。

<think>我们被要求回答关于执行shell脚本方法。根据提供的引用资料,我们可以总结出多种执行shell脚本的方式,并解释它们之间的区别。 引用[1]提到了4种执行方式,引用[2]详细描述了4种方法,引用[3]提到5种方式,引用[4]提到三种方式,引用[5]则是在Windows下通过bat运行sh脚本方法。 我们将综合这些资料,给出常见的执行shell脚本方法,并说明每种方法的特点和适用场景。 注意:在Linux/Unix环境下,执行shell脚本主要有以下几种方法: 1. 使用bash(或sh)命令执行脚本(作为解释器参数): ```bash bash script.sh ``` 或者 ```bash sh script.sh ``` 这种方法不需要脚本有可执行权限,脚本的第一行可以不用指定解释器(shebang),因为显式指定了bashsh执行。但是,如果脚本中使用了特定shell的特性(比如bash的数组),使用sh可能会出错(因为sh可能是链接到dash或其他轻量级shell)。 2. 使用绝对路径或相对路径执行(需要可执行权限): 首先,给脚本添加可执行权限: ```bash chmod +x script.sh ``` 然后,使用路径执行: ```bash ./script.sh # 当前目录下 /path/to/script.sh # 绝对路径 ``` 注意:这种方式要求脚本的第一行必须指定正确的解释器(如#!/bin/bash),否则会使用默认的shell执行,可能不符合预期。 3. 使用source命令或点号(.)执行: ```bash source script.sh ``` 或者 ```bash . script.sh ``` 这种方式会在当前的shell环境中执行脚本,而不是启动一个子shell。因此,脚本中定义的变量、函数等在脚本执行完毕后仍然存在当前shell中。通常用于加载环境变量配置文件(如~/.bashrc)。 4. 将脚本放在系统PATH包含的目录中,然后直接输入脚本执行(需要可执行权限): 例如,将脚本移动到/usr/local/bin或者~/bin(如果该目录在PATH中): ```bash mv script.sh /usr/local/bin/ # 需要sudo权限或对该目录有写权限 # 然后就可以在任何目录直接执行 script.sh ``` 同样,需要脚本有可执行权限,并且第一行指定解释器。 5. 在Windows下通过bat文件运行shell脚本(需要安装Git Bash或Cygwin等): 如引用[5]所示,通过调用bash.exe来执行.sh脚本: ```batch @set SHELL_SCRIPT_PATH="C:tool\Get_PS_data_script.sh" @set SHELL_BIN_DIR="C:\Program Files\Git\bin\bash.exe" @%SHELL_BIN_DIR% %SHELL_SCRIPT_PATH% ``` 区别总结: - 前两种方法bash/sh执行和路径执行)会在子shell执行脚本结束后子shell关闭,其环境变量等不会影响父shell- 第三种方法(source或点号)在当前shell执行,会影响当前shell的环境。 - 第四种方法实际上是第二种方法的便捷方式,也是运行在子shell中。 - 第五种方法是在Windows环境下模拟Linux环境执行。 注意:引用[3]提到,使用sh script.sh方法三)会改变脚本默认解释器类型(使用/bin/sh,即posix模式),可能会影响脚本中特定于bash的语法。 因此,在编写脚本时,建议在脚本首行指定解释器(如#!/bin/bash),然后根据情况选择执行方式。 如果用户需要了解更详细的内容,可以参考上述引用资料。 下面我们按照要求,用中文回答,并生成相关问题。 </think>### Shell脚本执行方法详解 执行Shell脚本主要有以下几种方式,它们在执行环境、权限要求和应用场景上存在显著差异: #### 一、基本执行方式 1. **解释器直接执行**(子shell环境) ```bash bash script.sh # 默认使用bash解释器 sh script.sh # 使用系统默认sh(可能是bash的POSIX模式)[^3][^4] ``` - ✅ 优点:无需执行权限 - ⚠️ 注意:可能改变默认解释器(如#!/bin/bash会被/bin/sh覆盖)[^3] - 💻 执行环境:创建新子shell,退出后环境变量不保留[^2] 2. **路径直接执行**(子shell环境) ```bash ./script.sh # 相对路径 /path/to/script.sh # 绝对路径 ``` - 🔑 要求:必须添加可执行权限 ```bash chmod +x script.sh ``` - 📌 关键:依赖脚本首行`#!/bin/bash`指定解释器 - 🌐 执行环境:创建新子shell[^2] #### 二、特殊执行方式 3. **当前Shell环境执行** ```bash source script.sh . script.sh # 点号+空格+脚本名(等效source) ``` - 🚩 特点:不创建子进程,在当前Shell直接执行 - 💡 应用:加载环境变量配置文件(如~/.bashrc)[^2] - ️ 风险:脚本中的`exit`会直接关闭当前终端 4. **远程执行** ```bash ssh user@server 'bash -s' < script.sh # 通过SSH执行远程脚本 ``` #### 三、跨平台执行 5. **Windows执行Linux脚本** ```batch :: DOS批处理示例 @set SHELL_SCRIPT_PATH="C:\path\to\script.sh" @set SHELL_BIN_DIR="C:\Program Files\Git\bin\bash.exe" @%SHELL_BIN_DIR% %SHELL_SCRIPT_PATH% [^5] ``` - 📦 前提:需安装Git Bash/WSL/Cygwin等兼容环境 - 🔗 原理:调用bash.exe解释器执行.sh文件 --- ### 执行方式对比总结 | **方式** | **是否需要x权限** | **执行环境** | **是否保留环境变量** | **典型场景** | |-------------------|------------------|-------------|---------------------|--------------------------| | `bash script.sh` | ❌ 不需要 | 子shell | ❌ 不保留 | 快速测试临时脚本 | | `./script.sh` | ✅ 需要 | 子shell | ❌ 不保留 | 正式部署的可执行脚本 | | `source script.sh`| ❌ 不需要 | 当前shell | ✅ 保留 | 加载环境配置、函数定义 | | SSH远程执行 | ❌ 不需要 | 远程shell | ❌ 不保留 | 跨服务器批量操作 | | Windows执行 | ❌ 不需要 | 兼容层shell | ⚠️ 部分保留 | Windows调用Linux脚本 | --- ### 最佳实践建议 1. **生产环境部署**:使用路径执行方式(`./script.sh`)+ 严格权限控制 2. **环境变量配置**:优先使用`source`方式加载配置 3. **跨平台兼容**: ```bash #!/usr/bin/env bash # 首行使用env查找解释器 ``` 4. **安全检查**: ```bash bash -n script.sh # 语法检查 bash -x script.sh # 调试模式 ``` --- ### 相关问题 1. 子shell环境与当前shell环境的主要区别是什么?[^2] 2. 如何在脚本退出后保留其设置的环境变量? 3. Shell脚本执行权限管理有哪些最佳实践? 4. 哪些方法可以调试执行中的Shell脚本? 5. 如何确保Shell脚本在不同Linux发行版上的兼容性? > 通过理解不同执行方式的底层机制,可有效避免环境污染、权限错误等问题,提升脚本可靠性和安全性[^1][^3][^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JXES智能生态系统

如文章对你有用,请作者喝个咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值