我为了实现一个功能,就是让PS1变量(命令行提示符)每隔1分钟(利用crontab计划任务)变化一次颜色和背景格式以实现酷炫的效果,可是通过了各类尝试均以失败了结。虽然可以实现让PS1每按一次回车变化一次颜色(这个有人想尝试的话下面写的有),可是没法作到让它每隔一段时间进行一次格式的变化
为了解决这个问题,进行了一些研究,总结了一下写在下面linux
先在脚本中写入:shell
#!/bin/bash PS1="\033[01;\$[RANDOM%7+31]m\A[\u@\h \w]\\$\033[0m "
注意点:centos
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
没定义localbash
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
定义localapp
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命令查看到的这些出现的变量都可以继承):ide
不可以被直接继承的有:函数
PS1:测试
PS2:centos7
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中直接使用