Ubuntu下运行Shell脚本提示"declare not found"的问题

本文探讨了Ubuntu系统中使用dash作为默认shell导致的问题,并对比bash的特点,提供了如何将默认shell从dash切换回bash的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<meta http-equiv="content-type" content="text/html; charset=utf-8">

此种问题只在 Ubuntu 下才会出现!安装 debian 系统根本不存在此类问题,因为只有Ubuntu 把默认的 bash 替换成了 dash.

在学习 Shell 脚本的时候,有两个例子在运行时出现异常。比如,我在 test-dash.sh脚本输入如下内容: 
echo -e "Trekshot. \a \n" 
declare -i number=7 
echo $number 
在 Ubuntu 系统下使用 sh test-bash.sh 运行将出现如下提示信息: 
-e Trekshot. 
test-dash.sh: 2: declare: not found: 

有两个问题: 
a. echo 的参数 '-e' 怎么也打印出来了? 
b. 一个简单的整数声明语句为何提示 "declare: not found"? 

1.出现此问题的原因并非代码本身有误,而是 Ubuntu 系统的问题。我们在编写脚本时,第一行经常要写这么一行内容:#!/bin/bash. 这是对该脚本所使用的 shell 进行声明,因为Linux 上的 shell 并非只有一种,而各个 shell 的语法是由差别的。之所以把 echo 命令的参数误打出来,就是因为 sh 命令没有理解该语法,即当前使用的并不是 bash.下面来证明: 
获取 /bin 中相关文件的属性: 
-rwxr-xr-x 1 root root 725136 2008-05-13 02:48 bash 
-rwxr-xr-x 1 root root 87924 2008-06-21 00:07 dash 
lrwxrwxrwx 1 root root 4 2010-03-25 14:29 sh -> dash 

这表明在执行 sh test-dash.sh 的时候,我们使用的是一个叫 "dash" 的命令(注意 sh实为链接文件),而并不是脚本第一行中声明的 bash. 这就是上面现象的原因。 其实,如果使用 bash test-dash.sh 命令执行的话,上面两个错误根本不会出现。 

2.dash(Debian Almquist SHell) Ubuntu 自 6.10 后,将先前的 bashshell 更换成了dash (有待考证). 在设置 dash 的说明中有下面文字: 

The default /bin/sh shell on Debian and Debian-based systems is bash. 

However, since the default shell is required to be POSIX-compliant, any 
shell that conforms to POSIX, such as dash, can serve as /bin/sh. You may 
wish to do this because dash is faster and smaller than bash. 

大致意思是说默认的 shell 是 bash shell, 但只要是能兼容 POSIX 的 shell 都可以,而dash 比 bash 速度更快、更小巧,因此 Ubuntu 安装了 dash. 

3.怎么能把 dash 去掉而使用默认的 bash?使用如下命令: 
sudo dpkg-reconfigure dash 
此命令是对已安装的包进行重新配置,在菜单(dash-bash-sh.png)中选择是否将 sh 链接到 dash (Install dash as /bin/sh?) 选择否即可。 

附图一:Ubuntu 下设置 dash 界面

ubuntu 设置 dash - 烈火网

### Shell脚本 `declare` 命令详解 #### 1. 基本用法 `declare` 命令用于声明变量并设置其属性。基本语法如下: ```bash declare 变量名 ``` 这仅声明了一个名为“变量名”的变量,未赋予任何初始值。 若需初始化变量,则可采用以下形式: ```bash declare 变量名=值 ``` 这里的“值”可以是字符串、整数或其他合法的数据类型[^4]。 #### 2. 设置变量属性 通过附加选项参数至 `declare` 后面来指定更多特性,例如作用范围或访问权限等。 - **只读变量** 创建不可更改的常量,一旦设定就不能再被修改或者删除: ```bash declare -r readonly_var="This is a constant" ``` - **数组声明** 定义索引数组或关联数组(键值对集合),分别适用于数值型下标和任意类型的键: ```bash # 数字索引数组 declare -a indexed_array=(one two three) # 字符串作为键的哈希表/映射 declare -A assoc_array=(["key"]="value") ``` - **函数局部变量** 当在函数内部创建临时性的本地存储空间时很有用处;离开该上下文后自动销毁这些实体: ```bash my_function() { local temp_variable="Local to function scope" echo $temp_variable } ``` - **名称引用** 利用 `-n` 参数建立别名指向另一个现有对象的位置而非复制它的内容,从而实现间接寻址机制: ```bash source_var="Original content" declare -n alias_name=source_var echo ${alias_name} # 输出 Original content alias_name="Changed!" echo ${source_var} # 输出 Changed! ``` - **导出环境变量** 将普通 shell 内部使用的简单标识符提升到全局进程级别可见度,使之成为操作系统层面认可的标准配置项之一: ```bash export PATH=$PATH:/new/path/addition # 或者更正式地说就是调用了带有 '-x' 的 declare 版本 declare -x NEW_ENV_VAR=value_for_all_processes ``` 上述功能使得 `declare` 成为了 bash 编程里不可或缺的一部分工具集成员,在编写复杂逻辑控制流程序期间提供了极大的灵活性和支持力度[^3]。 #### 3. 查看已定义变量详情 利用 `declare -p` 功能能够获取当前会话中存在的所有命名实体连同各自携带的信息一起展示出来,这对于排查错误以及理解代码运行状态特别有帮助[^2]: ```bash declare -p | less ``` 此命令将返回一系列由系统维护着的对象列表,每条记录都包含了完整的描述信息,如数据类别、尺寸大小乃至具体的取值情况等细节部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值