对话在bash不正确敛变量 [英] Dialog in bash is not grabbing variables correctly

查看:148
本文介绍了对话在bash不正确敛变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一点问题,这个脚本的一致性。您可以一次运行它,没有任何问题。但是,如果你立刻载入它并再次运行它,它不正确地抢变量,因为输出不会写入文件的正确方法。

例如:
此实用程序旨在从根本上更新4个文件。 .temp,.tiers,.version和.SYNC
在通过对话框提示不同阶段,它更新文件。我的问题是,有的时候也不能更新文件,我找不到任何原因的,因为它是只有在你已经跑了一次。我擦在启动时的文件,所以我不知道这笔交易是什么。这就像它完全从内存中抓住了吗?

在任何情况下,测试这个,你需要下面的文件/测试

感谢的人谁可以给我一些指导。

 猫.tiers
稳定= 1
发布= 2
测试版= 3

code:

 #!的/ usr / bin中/ env的庆典
触摸.version
触摸.temp
VERSION =`猫.version`
DIR = /测试/
STORED =`猫$ {DIR} /。temp`
################################
#重新排列TIERS#
################################
改编()
{
开始
结束
}
################################
#同步文件EXISTS#
################################
sync_exists()
{
对话框--msgbox.SYNC存在于目录$(回声$ {VERSION})。\\ n \\ n使用层移动来代替。 10 40
清理
1号出口;
}
################################
# 清理 #
################################
清理(​​)
{
室射频.version
室射频.update
室射频.temp
}################################
#OPTOUT&安培;清理 #
################################
选择退出()
{
对话框--msgbox你选择了退出一线的更新。 5 40
室射频$ {DIR} /。版本$ {DIR} /。更新$ {DIR} /。温度
}
################################
#UPDATE .TIERS FILE#
################################
tier_updater()
{
对话框--msgbox\\ n \\ n
$(猫$ {DIR} /。温度)现在是$ VERSION。8月27日
SED -i S / $ {}存储的=。* / $ {} STORED = $ {VERSION} / G $ {DIR} /。层
清理
}################################
#更新文件列表#
################################
file_updater()
{室射频$ {VERSION} /。同步
        在`$找到X版本型ð\\ | sed的S / $ {VERSION} // g`(-iname \\!);不要回声D === $ X === 755>> $ {DIR} / $ {VERSION} /同步。 DONE
        在`$找到VERSION型的F \\ Y | sed的S / $ {VERSION} // g`(-iname \\!*);不要回声F === $ Y === 644 ===`的md5sum $ {VERSION}$ Y| awk的'{$打印1}`>> $ {DIR}/$ VERSION/同步。DONE
        找到$ {DIR}/$ {VERSION}型的F -exec gzip的-f'{}'\\; >的/ dev / null的2 - ;&放大器; 1 | xargs的的gzip -d$ {DIR}/ $ {VERSION} /同步
}################################
#TIER更新提示#
################################
tier_update_prompt()
{
如果[-f $ {VERSION} /同步];然后sync_exists
其他file_updater
科幻
对话框--menu\\ n
目录列表构建的。\\ n
文件列表内置。\\ n
文件的COM pressed。\\ n
同步文件的地方。\\ n \\ n
你想更新层为$(猫$ {DIR} /。温度)?\\ 15 60 2是,这将适用于$至$猫$ {DIR}所有更改(回声$ VERSION)(/ 。.temp)无这将恢复所有的变更2方式>&功放; 1方式> $ {DIR} /更新
如果[$? =0];然后
        _Update = $(猫$ {DIR} /。更新)
如果[$ _Update=是];然后
tier_updater
科幻
如果[$ _Update=否];然后
选择退出 ;
科幻
其他
        回声您现在已经退出该应用程序
    清理;
科幻
}################################
#新版本INPUT#
################################
稳定()
{
对话框--inputbox输入$新版本(猫$ {DIR} / TEMP)。8月30日2 - ; $ {DIR}/版
如果[-d`猫.version`]。然后tier_update_prompt;
        其他
            对话框--msgbox警告!!!! \\ n \\ n该文件夹$($ {VERSION})不存在!\\ n请上传这个文件夹,然后再继续! 8 50;
        清理
    科幻
}################################
#TIER选择#
################################
启动()
{
对话框--menu层级当前设置为以下几点。你要哪一种更新吗?\\ n12 78 5 \\
稳定,$(猫$ {DIR} /层|。grep的稳定| sed的'S /稳定= // G')发行,$(猫$ {DIR} /层|。grep的发布| sed的' S /释放= // G')。测试版$(猫$ {DIR} /层| grep的Beta版| sed中的/β= // G')2 - ; $ {DIR}/温度
#确定为pressed
如果[$? =0];然后
        _return = $(猫$ {DIR} /。温度)
科幻
如果[$ _return=稳定];然后
稳定
科幻
如果[$ _return=释放];然后
稳定
科幻
如果[$ _return=测试版];然后
稳定
    其他
            回声您现在已经退出该应用程序
    清理;
科幻
}


解决方案

您可以使用该方法来捕获对话框otput直接进入变量:

  EXEC 3 GT;&放大器; 1
结果= $(对话框--menu头15 20 6 $(为((i = 1; I< 30;我++));做回声标签$ I项目$我;做)2 - ;&放大器; 1>及3 );
退出code = $ ?;
EXEC 3>&放大器; - ;
回声$结果$退出code

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

所以用我的方法启动看起来像:

 启动()
{
  EXEC 3>&放大器; 1
  _return = $(对话框--menu层级当前设置为以下哪你想更新吗?\\ n12 78 5 \\
  稳定,$(猫$ {DIR} /层|。grep的稳定| sed的'S /稳定= // G')发行,$(猫$ {DIR} /层|。grep的发布| sed的' S /释放= // G')。测试版$(猫$ {DIR} /层| grep的Beta版| sed中的/β= // G')2>&放大器; 1>及3 )
   退出code = $?
   EXEC 3>&放大器; - ;
    #确定为pressed
  如果[$退出code==0];然后
    如果[$ _return==稳定|| $ _return==释放|| $ _return==测试版]
    然后
       稳定
    科幻
  科幻
  回声您现在已经退出该应用程序
  清理;
}

additionaly很多不干净的东西像$($ {VERSION})位置:

 对话框--msgbox警告!!!! \\ n \\ n该文件夹$($ {VERSION})不

我从$ C $明白了c那么它就会耗尽命令.version是空的启动和

  VERSION =`猫.version`

在tier_update_prompt()
$ VERSION还是空的字符串,

我想你难治code,但它把它搞砸,以竟有如此建议:


  • 得到对话框的结果正如我上面显示

  • 带参数运行的功能:


#宣言
函数名(){
  参数= $ 1;
  回声$参数
}
VAR值=
#run功能
FUNCTION_NAME VAR


  • 请不要使用$ {VAR}
  • 超集成
  • 记住双引号的扩展,回声这里是$ VAR而不是回声这里是$(回声$ {VAR})

  • 使用较少作为临时文件,你可以,例如:差异≤(LS DIR1)≤(LS DIR2)

  • 请不要保存在根目录下工作的文件(如/测试/)

  • 请不要以root身份运行

  • 学Perl

I'm having a bit of problem with the consistency of this script. You can run it once, without any issues. However if you immediately load it back up and run it again, it doesn't grab the variables correctly because the output isn't written to the files the right way.

Ex: This utility is designed to essentially update 4 files. .temp, .tiers, .version, and .sync Upon various stages through dialog prompts, it updates a file. My problem is, some times it doesn't update the file and I cannot find any cause as it's only after you've already ran it once. I wipe the files at start up, so I'm not sure what the deal is. It's like it's grabbing it solely from memory?

At any rate, to test this you'll need the below file in /test

Thanks for anyone who can give me some guidance.

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

CODE:

#!/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 -i s/${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
}

解决方案

You can use that method to capture dialog otput directly into variable:

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

so with my approach startup will look like:

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;
}

additionaly many unclean things like $(${VERSION}) here:

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

as i understand from code it will run empty command as .version is empty on startup and

 VERSION=`cat .version`

in tier_update_prompt() $VERSION still empty string,

I tried to refactory your code, but it turn that it messed to much so suggestions:

  • get dialog results as i shown above
  • run functions with parameters:

#declaration
function_name() { 
  parameter=$1;
  echo "$parameter"
}
var=value
#run function
function_name var     

  • do not overcomplexity with ${VAR},
  • remember that double quotes expands, so echo "here is $var" instead of echo "here is $(echo ${var})"
  • use as less temporary files as you can for example: diff <(ls dir1) <(ls dir2)
  • do not keep working files in root directory (like /test/)
  • do not work as root
  • learn perl

这篇关于对话在bash不正确敛变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆