我爲了實現一個功能,就是讓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中直接使用