对话在bash不正确敛变量 [英] Dialog in bash is not grabbing variables correctly
问题描述
我有一点问题,这个脚本的一致性。您可以一次运行它,没有任何问题。但是,如果你立刻载入它并再次运行它,它不正确地抢变量,因为输出不会写入文件的正确方法。
例如:
此实用程序旨在从根本上更新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 ofecho "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屋!