bash中的对话框不能正确地获取variables

我对这个脚本的一致性有点问题。 你可以运行一次,没有任何问题。 但是,如果立即将其加载并重新运行,则不会正确获取variables,因为输出不会以正确的方式写入文件。

例如:该实用程序旨在更新4个文件。 .temp,.tiers,.version和.sync通过对话提示的各个阶段,它会更新一个文件。 我的问题是,有些时候它不会更新文件,我不能find任何原因,因为它只有在你已经运行一次。 我在启动时擦除了文件,所以我不确定这个交易是什么。 这就像是从内存中抓取它?

无论如何,要testing这个,你需要在/ test下面的文件

感谢任何能给我一些指导的人。

cat .tiers Stable=1 Release=2 Beta=3 

码:

 #!/usr/bin/env bash touch .version touch .temp VERSION=`cat .version` DIR=/test/ STORED=`cat ${DIR}/.temp` ################################ # REARRANGE TIERS # ################################ rearrange() { start end } ################################ # SYNC FILE EXISTS # ################################ sync_exists() { dialog --msgbox ".sync exists in the directory $(echo ${VERSION}).\n\n Use Tier Move instead." 10 40 clean_up exit 1; } ################################ # CLEAN UP # ################################ clean_up() { rm -rf .version rm -rf .update rm -rf .temp } ################################ # OPTOUT & CLEAN UP # ################################ opt_out() { dialog --msgbox "You've opted out of the tier update." 5 40 rm -rf ${DIR}/.version ${DIR}/.update ${DIR}/.temp } ################################ # UPDATE .TIERS FILE # ################################ tier_updater() { dialog --msgbox "\n\n $(cat ${DIR}/.temp) is now $VERSION." 8 27 sed -is/${STORED}=.*/${STORED}=${VERSION}/g ${DIR}/.tiers clean_up } ################################ # UPDATE FILE LIST # ################################ file_updater() { rm -rf ${VERSION}/.sync for x in `find $VERSION -type d \( ! -iname "." \)|sed s/${VERSION}//g`; do echo "d===$x===755" >> ${DIR}/${VERSION}/.sync ; done for y in `find $VERSION -type f \( ! -iname ".*" \)|sed s/${VERSION}//g`; do echo "f===$y===644===`md5sum ${VERSION}"$y"|awk '{print $1}'`" >> "${DIR}"/"$VERSION"/.sync;done find "${DIR}"/"${VERSION}" -type f -exec gzip -f '{}' \; > /dev/null 2>&1 |xargs gzip -d "${DIR}"/${VERSION}/.sync } ################################ # TIER UPDATE PROMPT # ################################ tier_update_prompt() { if [ -f ${VERSION}/.sync ]; then sync_exists else file_updater fi dialog --menu "\n Directory List Built.\n File List Built.\n Files Compressed.\n Sync File in place.\n\n Would you like to update the tier for $(cat ${DIR}/.temp)?" \ 15 60 2 "Yes" "This will apply all changes for $(echo $VERSION) to $(cat ${DIR}/.temp)." "No" "This will revert all changes." 2>&1 > ${DIR}/.update if [ "$?" = "0" ] ; then _update=$(cat ${DIR}/.update) if [ "$_update" = "Yes" ] ; then tier_updater fi if [ "$_update" = "No" ] ; then opt_out ; fi else echo "You have now exited the application" clean_up; fi } ################################ # NEW VERSION INPUT # ################################ stable() { dialog --inputbox "Enter the new version for $(cat ${DIR}/.temp)" 8 30 2> "${DIR}"/.version if [ -d `cat .version` ] ; then tier_update_prompt; else dialog --msgbox "WARNING!!!!\n\n The folder $(${VERSION}) does not exist!\nPlease upload this folder before you proceed!" 8 50 ; clean_up fi } ################################ # TIER SELECTION # ################################ startup() { dialog --menu "Tiers are currently set as the following. Which would you like to update? \n" 12 78 5 \ "Stable" "$(cat ${DIR}/.tiers|grep Stable|sed 's/Stable=//g')" "Release" "$(cat ${DIR}/.tiers|grep Release|sed 's/Release=//g')" "Beta" "$(cat ${DIR}/.tiers|grep Beta|sed 's/Beta=//g')" 2> "${DIR}"/.temp # OK is pressed if [ "$?" = "0" ] ; then _return=$(cat ${DIR}/.temp) fi if [ "$_return" = "Stable" ] ; then stable fi if [ "$_return" = "Release" ] ; then stable fi if [ "$_return" = "Beta" ] ; then stable else echo "You have now exited the application" clean_up; fi } 

Solutions Collecting From Web of "bash中的对话框不能正确地获取variables"

您可以使用该方法直接捕获对话框输入到变量中:

 exec 3>&1 result=$(dialog --menu head 15 20 6 $(for ((i=1;i<30;i++));do echo tag$i item$i;done) 2>&1 1>&3); exitcode=$?; exec 3>&-; echo $result $exitcode 

http://mywiki.wooledge.org/BashFAQ/002

所以我的方法startup将如下所示:

 startup() { exec 3>&1 _return=$(dialog --menu "Tiers are currently set as the following. Which would you like to update? \n" 12 78 5 \ "Stable" "$(cat ${DIR}/.tiers|grep Stable|sed 's/Stable=//g')" "Release" "$(cat ${DIR}/.tiers|grep Release|sed 's/Release=//g')" "Beta" "$(cat ${DIR}/.tiers|grep Beta|sed 's/Beta=//g')" 2>&1 1>&3) exitcode=$? exec 3>&-; # OK is pressed if [ "$exitcode" == "0" ] ; then if [[ "$_return" == "Stable" || "$_return" == "Release" || "$_return" == "Beta" ]] then stable fi fi echo "You have now exited the application" clean_up; } 

除此之外,还有许多不洁净的东西,例如$($ {VERSION}):

 dialog --msgbox "WARNING!!!!\n\n The folder $(${VERSION}) does not 

正如我从代码理解它将运行空的命令为.version在启动时是空的

  VERSION=`cat .version` 

在tier_update_prompt()$ VERSION中仍然是空字符串,

我试图重构你的代码,但它变成了很多建议:

  • 得到对话结果,如上所示
  • 使用参数运行函数:
 #宣言
 function_name(){ 
  参数= $ 1;
  回声“$参数”
 }
 VAR =值
 #run函数
函数名称var     

  • 不要与$ {VAR}过度复杂,
  • 请记住,双引号扩展,所以echo "here is $var"而不是echo "here is $(echo ${var})"
  • 比如使用更少的临时文件: diff <(ls dir1) <(ls dir2)
  • 不要在根目录下保存工作文件(如/ test /)
  • 不要以root身份工作
  • 学习perl