shell变量详解

1 shell变量基础
shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义。所以若要进行数学运算,必须使用一些命令例如let、declare、expr、双括号等。shell变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell中可用。而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shell变量。变量名必须以字母或下划线字符开头。其余的字符可以是字母、数字(0~9)或下划线字符。任何其他的字符都标志着变量名的终止。名字是大小写敏感的。给变量赋值时,等号周围不能有任何空白符。为了给变量赋空值,可以在等号后跟一个换行符。用set命令可以查看所有的变量,unset var命令可以清除变量var,var相当于没有定义过。readonly var可以把var变为只读变量,定义之后不能对var进行任何更改。对shell变量的引用方式很多,用这些方式可以方便的获取shell变量的值,变量值的长度,变量的一个字串,变量被部分替换后的值等等。shell变量常见引用方式如下:

2 环境变量
环境变量的定义方法如下:
var=value
export var
shell在初始化的时候会在执行profile等初始化脚本,脚本中定义了一些环境变量,这些变量会在创建子进程时传递给子进程。
用env命令可以查看当前的环境变量。常用的系统环境变量如下:
_(下划线) 上一条命令的最后一个参数
BASH 展开为调用bash实例时使用的全路径名
CDPATH cd命令的搜索路径。它是以冒号分隔的目录列表,shell通过它来搜索cd命令指定的目标目录。例如.:~:/usr
EDITOR 内置编辑器emacs、gmacs或vi的路径名
ENV 每一个新的bash shell(包括脚本)启动时执行的环境文件。通常赋予这个变量的文件名是.bashrc。
EUID 展开为在shell启动时被初始化的当前用户的有效ID
GROUPS 当前用户所属的组
HISTFILE 指定保存命令行历史的文件。默认值是~/.bash_history。如果被复位,交互式shell退出时将不保存命令行历史
HISTSIZE 记录在命令行历史文件中的命令数。默认是500
HOME 主目录。未指定目录时,cd命令将转向该目录
IFS 内部字段分隔符,一般是空格符、制表符和换行符,用于由命令替换,循环结构中的表和读取的输入产生的词的字段划分
LANG 用来为没有以LC_开头的变量明确选取的种类确定locale类
OLDPWD 前一个工作目录
PATH 命令搜索路径。一个由冒号分隔的目录列表,shell用它来搜索命令,一个普通值为 /usr/gnu/bin:/usr/local/bin:/usr/ucb:/usr/bin
PPID 父进程的进程ID
PS1 主提示符串,默认值是$
PS2 次提示符串,默认值是>
PS3 与select命令一起使用的选择提示符串,默认值是#?
PS4 当开启追踪时使用的调试提示符串,默认值是+。追踪可以用set –x开启
PWD 当前工作目录。由cd设置
RANDOM 每次引用该变量,就产生一个随机整数。随机数序列可以通过给RANDOM赋值来初始化。如果RANDOM被复位,即使随后再设置,它也将失去特定的属性
REPLY 当没有给read提供参数时设置
SHELL 当调用shell时,它扫描环境变量以寻找该名字。shell给PATH、PS1、PS2、MAILCHECK和IFS设置默认值。HOME和MAIL由login(1)设置
SHELLOPTS 包含一列开启的shell选项,比如braceexpand、hashall、monitor等
UID 展开为当前用户的用户ID,在shell启动时初始化
3 数值变量
shell中默认把变量值当作字符串,例如:
age=22
age=${age}+1
echo ${age}
输出结果为22+1,而不是23,因为shell将其解释为字符串,而不是数学运算。
可以用let命令使其进行数学运算,例如:
let age=${age}+1
也可以用declare把变量定义为整型。例如:
declare -i age=22
这里就用 -i 选项把age定义为整型的了。此后每次运算,都把age的右值识别为算术表达式或数字。
4 数组
在shell中可以使用数组,例如:
array[0]=0
array[1]=1
array[2]=2
则array就是一个数组,也可以这样给数组初始化:
array=(0 1 2) // 元素之间以空格分隔
可以通过 ${array[$i]}来访问array中某个元素,${array[*]} 的返回值即数组的所有元素组成的串,${#array[*]} 的返回值即数组的元素个数,${array[*]:0:2} 返回第一个和第二个元素组成的串。0表示开始的位置,2表示要返回的元素个数,开始位置可以为0-2(0减去2)之类的,表示从倒数第二个元素开始。
下面写个稍微复杂点的例子:

复制代码
1 #!/bin/bash
2 for ((i=0; i<100; i++))
3 do
4 array[$i]=$i
5 done
6 for ((i=0; i<100; i++))
7 do
8 echo ${array[$i]}
9 done
复制代码

如果要使用二维数组甚至三维数组该怎么实现呢,那就需要用eval命令来模拟数组的功能了。
eval命令的作用是扫描命令两次再执行,如果不使用eval,只扫描一次,然后执行。看个例子:
root@suse:~$ name=Barry
root@suse:~$ $name=hello
Barry=hello: command not found
为什么第二句给Barry变量赋值会出错呢?从报错信息可以发现shell并没有识别这是个赋值语句,而是把Barry=hello当作一个命令来执行,当然会报错。为什么不能识别这是赋值语句呢?第一次扫描时,因为扫描到$符号,所以不能把这句当作赋值语句,赋值语句的左边总是一个变量名,而不应该是$开头的。所以第一次扫描仅仅识别了$name变量,并做了替换,而并没有认识到赋值语句。
如果使用eval $name=hello呢?
root@suse:~$ name=Barry
root@suse:~$ $name=hello
Barry=hello: command not found
root@suse:~$ eval $name=hello
root@suse:~$ echo $Barry
hello
可见使用了eval之后,对 $name=hello 第一次扫描替换了$name,没有识别赋值语句,第二次扫描识别是赋值语句,然后执行。现在大约可以想到怎样用eval实现二维数组了。
下面实现的二维数组每一行代表一个人的信息记录,包括姓名,年龄。

复制代码
 1 for ((i=0; i<2; i++))
 2 do
 3 for ((j=0; j<2; j++))
 4 do 
 5 read man$i$j
 6 done
 7 done
 8 echo "next print:"
 9 for ((i=0; i<2; i++))
10 do
11 for ((j=0; j<2; j++))
12 do 
13 eval echo -n "\$man$i$j:"
14 done
15 printf "\n"
16 done
复制代码

5 特殊变量
$0:当前脚本的文件名
$num:num为从1开始的数字,$1是第一个参数,$2是第二个参数,${10}是第十个参数
$#:传入脚本的参数的个数
$*:所有的位置参数(作为单个字符串) 
$@:所有的位置参数(每个都作为独立的字符串)。
$?:当前shell进程中,上一个命令的返回值,如果上一个命令成功执行则$?的值为0,否则为其他非零值,常用做if语句条件
$$:当前shell进程的pid
$!:后台运行的最后一个进程的pid
$-:显示shell使用的当前选项
$_:之前命令的最后一个参数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PB datawindow中的文本调整打印长度

long row_count if right(label_text,1) ‘、’ then//label_text是在外面定义的全局变量&#xff08;Instance&#xff09; label_text left (label_text,len(label_text) -1) end if row_count ceiling(len(label_text) / 33) dw_print_nxs.modify("expand2_1.heigh…

redis php怎么使用教程,PHP 使用redis

connect($host, $port);if ($ret false) {die($redis->getLastError());}$ret $redis->auth($user . "-" . $pwd . "-" . $dbname);if ($ret false) {die($redis->getLastError());}/*接下来就可以对该库进行操作了&#xff0c;具体操作方法请…

Ubuntu apache 禁止目录浏览

$ sudo vim /etc/apache2/sites-enabled/000-default 将Options后面Indexes前面加上"-"表示禁止目录浏览&#xff1a; <Directory /var/www/> Options -Indexes ...... </Directory> 然后重启apache $sudo service apache2 restart 转载于:https://www.…

CMake命令之list

用途&#xff1a;提供一些列表操作 list(LENGTH <list><output variable>) list(GET <list> <elementindex> [<element index> ...] <output variable>) list(APPEND <list><element> [<element> ...]) li…

python内函数名加括号和不加括号的区别,python中 函数名加括号与不加括号

Maven之自定义archetype生成项目骨架&lpar;一&rpar;Maven之自定义archetype生成项目骨架(一) 标签: mavennexus插件 2015-07-15 16:40 2443人阅读 评论(0) 收藏 举报 分类: Maven技术(9) ...Effective Objective-C 2&period;0 — 第9条&#xff1a;以&OpenCu…

POST

NSURL *url [NSURL URLWithString:"https://www.baidu.com"];NSMutableURLRequest *request [NSMutableURLRequest requestWithURL:url];request.HTTPMethod "POST";// 请求参数NSString *bodyStr [NSString stringWithFormat:"username%&pas…

CMake 手册详解(二十二)

原文地址 http://www.cnblogs.com/coderfenghc/archive/2012/10/20/2712806.html CMD#65: separate_arguments 将空格分隔的参数解析为一个分号分隔的list。 separate_arguments(<var> <UNIX|WINDOWS>_COMMAND "<args>") 解析一个unix或者windows…

websocket多人聊天php,php-notes/基于websocket实现多人聊天室.md at master · dd-code-site/php-notes · GitHub...

WebSocket连接断开格式&#xff1a;ws://IP或域名:端口发送消息var websocket;var wsUrl;function connect(){try {wsUrl $(#wsUrl).val();websocket new WebSocket(wsUrl);websocket.onopen function(event){console.log(客户端与服务端连接成功);connectChangeButton();al…

cmake学习(二)常用变量和常用环境变量

一、变量的引用方式是使用“${}”&#xff0c;在IF中&#xff0c;不需要使用这种方式&#xff0c;直接使用变量名即可 二、自定义变量使用SET(OBJ_NAME xxxx)&#xff0c;使用时${OBJ_NAME}三、cmake的常用变量&#xff1a;CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR&am…

if和case用法比较

Case语句时并发语句&#xff0c;需要采用并行逻辑来实现&#xff0c;不存在逻辑的优先级别。If……else语句时多级嵌套语句&#xff0c;通常采用逻辑的串联来实现&#xff0c;该结构具有优先级别问题。这两种结构分别如下图所示&#xff1a; Always (a or b or c or d or s[1:…

CMake的使用

一、 基本使用 安装&#xff1a;下载二进制包后可直接解压使用 从源码安装则执行命令&#xff1a;./bootstrap; make; make install——尝试执行bootstrap失败 使用&#xff1a;cmake dir_path&#xff0c;生成工程文件或makefile文件 二、 概念 out-of-source …

PHP实训笔记,【学习笔记19】实验吧 让我进去

知识点MD5拓展攻击解题思路打开网站后看到&#xff0c;什么都没有&#xff0c;尝试抓包分析360截图17860604827894.PNGBurp 抓包发现&#xff0c;Cookie有东西。先是把source0改成source1,得到源码。、、、$flag "XXXXXXXXXXXXXXXXXXXXXXX";$secret "XXXXXXXX…

CMake PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR区别

看了好多网上的文章&#xff0c;都说PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR是等价的。 实际不然。 一般来说&#xff0c;都是这样用 cmake ./ 这样PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR是等价的。也就是当前源码的目录。 如果执行cmake的时候&#xff0c;并不在源码…

toolStrip 按钮图片大小的修改

http://www.cnblogs.com/smallsoftfox/archive/2012/06/21/2558323.html转载于:https://www.cnblogs.com/PatrickLee/p/3526708.html

oracle11g数据文件路径,oracle11g trace路径和diagnostics路径的变化

Oracle11g中trace文件和日志文件的路径发生了变化在$ORACLE_BASE/diag建立了一些分类目录&#xff0c;用来保存各种日志&#xff1a;[oraclerac1 trace]$ cd $ORACLE_BASE[oraclerac1 oracle]$ cd diag[oraclerac1 diag]$ pwd/u01/app/oracle/diag[oraclerac1 diag]$ lsasm cli…

qt for v210

1. v210本身自带了qt4.8.4的qt库&#xff0c;路径在/usr/lib下面。但是我们需要对屏幕进行90度旋转。因此需要重新编译qt库。 我们编译了qt4.8.5的qt库&#xff0c;把/usr/lib下面libQt*删除&#xff0c;将编译好的libQt*拷贝过来即可。 2. 因为我们只用自己增加的文泉驿字体&…

DataGridView数据导入到Excel 中

#region DataGridView数据显示到Excel /// <summary> /// 打开Excel并将DataGridView控件中数据导出到Excel /// </summary> /// <param name"dgv">DataGridView对象 </param> /// <param name"isShowExcle">是…

cmake学习(一)静态库与动态库构建

(.so)共享库&#xff0c;shared object&#xff1a;节省空间&#xff0c;在运行时去连接&#xff0c;如果执行机器上没有这些库文件就不能执行。(.a)静态库,archive&#xff1a;静态库和程序化为一体&#xff0c;不会分开。通过 ldd命令可以查看一个可执行程序所依赖的的共享库…

oracle查表占的物理空间,查询Oracle表实际物理使用大小

Oracle中有两种含义的表大小一种是分配给一个表的物理空间数量&#xff0c;而不管空间是否被使用。可以这样查询获得字节数&#xff1a;select segment_name, bytesfrom user_segmentswhere segment_type TABLE;效果如下&#xff1a;或者Select Segment_Name,Sum(bytes)/1024/…

分布模式

Remote Facade远程外观 在OO模型中,存在很多规模小,且有小方法的对象.这些小对象会导致很多的对象间交互.在单一地址空间里,小对象没问题.但是,当在两个进程间做调用时,频繁的跨进程交互会造成性能开销.远程外观,减少远程调用的次数. 建立在大量的细粒度对象之上,提供一个粗粒度…