标签:环境变量配置 覆盖 linux ted lin name 就是 中括号 local
1.问题出现:我为了实现一个功能,就是让PS1变量(命令行提示符)每隔1分钟(利用crontab计划任务)变化一次颜色和背景格式以实现酷炫的效果,但是经过了各种尝试均以失败告终。虽然能够实现让PS1每按一次回车变化一次颜色(这个有人想尝试的话下面写的有),但是无法做到让它每隔一段时间进行一次格式的变化
为了解决这个问题,进行了一些研究,总结了一下写在下面
先在脚本中写入:
#!/bin/bash
PS1="\033[01;\$[RANDOM%7+31]m\A[\u@\h \w]\\$\033[0m "
注意点:
11:01[root@centos7 /data/scriptest]# echo $PS1
\033[01;$[RANDOM%7+31]m\A[\u@\h \w]\$\033[0m
20:59[root@centos7 /data/scriptest]# declare -x aaa=12345
20:59[root@centos7 /data/scriptest]# echo $aaa
12345
20:59[root@centos7 /data/scriptest]# ./testsource2.sh
12345
123123
20:59[root@centos7 /data/scriptest]# echo $aaa
12345
没定义local
21:01[root@centos7 /data/scriptest]# echo $aaa
12345
21:01[root@centos7 /data/scriptest]# funsor() { aaa=555 ; return 0 ; }
21:02[root@centos7 /data/scriptest]# echo $aaa
12345
21:02[root@centos7 /data/scriptest]# funsor
21:02[root@centos7 /data/scriptest]# echo $aaa
555
定义local
21:08[root@centos7 /data/scriptest]# echo $aaa
12345
21:08[root@centos7 /data/scriptest]# funsor2() { local aaa=555 ; echo $aaa ; return 0 ; }
21:08[root@centos7 /data/scriptest]# funsor2
555
21:08[root@centos7 /data/scriptest]# echo $aaa
12345
而能够被这个子shell直接继承的有(基本上在开机后shell开启后用declare -x命令查看到的这些出现的变量都能够继承):
不能够被直接继承的有:
PS1:
PS2:
PS4:
#!/bin/bash
echo PS1=$PS1
echo PS2=$PS2
echo PS3=$PS3
echo PS4=$PS4
select i in test1 test2 test3; do
case $i in
*)
echo $i
break
;;
esac
done
12:10[root@centos7 /data/scriptest]# . PStest
PS1=\[\033[01;35m\]\A[\u@\h \w]\$\[\033[00m\]
PS2=>
PS3=
PS4=+
1) test1
2) test2
3) test3
#? 2
test2
12:10[root@centos7 /data/scriptest]#
12:15[root@centos7 /data/scriptest]# declare -x PS1 PS2 PS3 PS4
12:15[root@centos7 /data/scriptest]# declare -x : 查看
declare -x PS1="\\[\\033[01;35m\\]\\A[\\u@\\h \\w]\\\$\\[\\033[00m\\] "
declare -x PS2="> "
declare -x PS3
declare -x PS4="+ "
12:15[root@centos7 /data/scriptest]# PStest
PS1=
PS2=
PS3=
PS4=+
1) test1
2) test2
3) test3
#? 1
test1
12:17[root@centos7 /data/scriptest]#
12:21[root@centos7 /data/scriptest]# PS3="Please input"
12:22[root@centos7 /data/scriptest]# PS4="=== "
12:22[root@centos7 /data/scriptest]# declare -x
declare -x PS1="\\[\\033[01;35m\\]\\A[\\u@\\h \\w]\\\$\\[\\033[00m\\] "
declare -x PS2="> "
declare -x PS3="Please input"
declare -x PS4="=== "
12:22[root@centos7 /data/scriptest]# PS1test.sh
12:24[root@centos7 /data/scriptest]# PStest
PS1=
PS2=
PS3=Please input
PS4=+
1) test1
2) test2
3) test3
Please input3
test3
先写脚本,然后以子shell方式进行测试:
21:36[root@centos7 /data/scriptest]# cat testsource.sh -n
1 #!/bin/bash
2 echo PATH=$PATH
3 echo PWD=$PWD
4 echo HOSTNAME=$HOSTNAME
5 echo HISTSIZE=$HISTSIZE
6 echo HISTCONTROL=$HISTCONTROL
7
21:36[root@centos7 /data/scriptest]# ./testsource.sh
PATH=/data/app/httpdnew/bin:/data/app/cmatrix/bin:/data/app/tree/bin:/data/scriptest/:.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/root/bin
PWD=/data/scriptest
HOSTNAME=centos7.6test
HISTSIZE=1000
HISTCONTROL=ignoreboth
它的执行过程比较特殊,它执行的时候并不会从当前shell中继承各种系统定义的环境变量和自己定义的环境变量(全局变量)等等,因此必须在它执行的时候传递给它各种环境变量才能保证后的命令完全正确的执行。分情况分析:
从上面可见crontab几乎不会继承任何变量,不论是系统定义的还是自己定义的,不论是环境还是普通变量,不论是内存中的还是文件中的。
它也是开启了一个子shell,不过与bash shell的区别就在于环境变量不会继承。因此为了命令的正确进行,可有下面的比较推荐的两种解决方式:
21:37[root@centos7 /data/scriptest]# cat /etc/crontab
//就是按照下面这3行的格式来定义自己需要的环境变量
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
source的命令其实很简单,就相当于是在当前的shell中执行文件中的命令(把文件中的每一行命令拉到命令行来执行),类似于函数,因此它能够改变当前shell的环境变量等等。
这也是为何我们用source来进行配置文件(尤其是环境变量)的修改之后让它生效的,而不是用 “bash 脚本” 或者添加PATH和执行权限后直接执行脚本的方式来修改环境变量。
因为后两种方式修改的环境变量只能在子脚本(shell)中有效,而前面说过虽然子脚本能继承环境变量(除了那些特殊的比如PS1,就算父shell修改PS1定义为环境变量,当开启子shell后它在子shell中也默认为空值没有定义),但是修改这些环境变量的值并不能返回到父shell中,也就实现不了使配置文件生效的目的了(其实生效了,不过是在子shell中生效的,子shell一旦退出所有配置便消失不能传给父shell)
从上面分析得知,不论怎样都无法在子shell中修改环境变量(包括PS1)的值并传给父shell,而crontab默认开启子shell,因此它不仅改不了PS1,其他的环境变量也无法应用到父shell中,就算用source命令也只是在crontab开启的子shell中应用这些环境变量,不能修改它们传递到父shell也就是当前shell中。
这个在crontab中代表换行,想要使用它要么\%转义的方式,要么就把它写入脚本中,或者写在单引号中不需要转义,不过此时就不能用于计算取余或者字符串变量操作中的一些命令了。
但是注意别忘了%它不能在crontab中直接使用
Linux的PS1.PS2.PS3.PS4等环境变量;Crontab的两个坑人点;变量传递等
标签:环境变量配置 覆盖 linux ted lin name 就是 中括号 local
原文地址:https://blog.51cto.com/14228129/2384429