Bash-使用一个";“静态”;变量(又名命令行俄语轮盘赌)

Bash-使用一个";“静态”;变量(又名命令行俄语轮盘赌),bash,Bash,TL;DR:如何在第一次运行bash脚本时设置变量,并在以后运行时修改它(类似于C中函数中的静态变量) 背景信息: Bash中的以下一行用于玩“命令行俄罗斯轮盘赌”(一个更安全的版本): 然而,它并不像普通的俄罗斯轮盘赌那样有效(在前6次尝试中,你肯定会在其中一次轮盘中有一颗子弹) 是否有办法确保出现这种情况(即在前6次尝试中保证出现*Boom*)。代码应该是可重复的(即完全相同的代码应该能够被复制粘贴一次又一次,而不是它的一部分),并且应该正常工作 我的想法是:设置一个变量,最初设置为$[$R

TL;DR:如何在第一次运行bash脚本时设置变量,并在以后运行时修改它(类似于C中函数中的
静态
变量)

背景信息:

Bash中的以下一行用于玩“命令行俄罗斯轮盘赌”(一个更安全的版本):

然而,它并不像普通的俄罗斯轮盘赌那样有效(在前6次尝试中,你肯定会在其中一次轮盘中有一颗子弹)

是否有办法确保出现这种情况(即在前6次尝试中保证出现
*Boom*
)。代码应该是可重复的(即完全相同的代码应该能够被复制粘贴一次又一次,而不是它的一部分),并且应该正常工作

我的想法是:设置一个变量,最初设置为
$[$RANDOM%6]
,然后在每次运行代码时递减。如果变量达到0,枪将移动
*动臂*
,否则,它将
*单击*
s。但是,我无法理解如何仅在第一次运行时设置变量,而不是在以后的运行中设置变量


警告:执行代码的风险由您自己承担。

我认为没有其他方法可以在不使用文件的情况下保存值。因此,如果要使用文件,可以使用以下命令:

f=/tmp/a; test -f $f || echo $(($RANDOM%6))>$f; test $(<$f) == "0" && echo *Boom* && rm $f; test -f $f && echo *Click* && echo $(($(<$f)-1))>$f
生成一个介于0和5之间的随机数,并将其存储在文件中:

test -f $f || echo $(($RANDOM%6))>$f;
test $(<$f) == "0" && echo *Boom* && rm $f;
如果文件中的内容为0,则打印Boom并删除该文件:

test -f $f || echo $(($RANDOM%6))>$f;
test $(<$f) == "0" && echo *Boom* && rm $f;

test$(简短回答:不,bash没有“静态”变量

更长:当“C”程序完成运行时,“static”变量将丢失。bash脚本也将丢失该变量。因此,您必须决定需要什么:

  • 运行脚本一次,模拟左轮手枪(可以使用全局变量保持左轮手枪状态)
  • 希望在每次脚本运行之间保留转轮的圆柱体状态,因此需要使用一些外部存储来保存数据(例如文件)
从你的问题我猜到了第二个版本,所以你必须使用文件来保存左轮手枪状态。对于游戏,你应该将问题分为不同的部分:

  • 滚动-(滚动左轮手枪的气缸(随机子弹位置))
  • 射击-(将气缸移动一个位置并检查子弹)
我会这样做:

  • 定义
    旋转器
    ,例如
    /tmp/revolver

    • 它将有6行,每行可以有2个值:
      0
      -无项目符号,
      1
      -项目符号
    • 锤子在第1行-因此,如果子弹在第1行(例如,第1行的值为1),子弹将开火
    • 每一个“滚动”都能确保气缸中有不止一颗子弹
    • 射击时-子弹一旦发射,将不会再次发射,因此任何数量的后续射击都不会再次发射
  • roll
    “命令”。定义为bash函数,另存为
    /roll
    命令

  • 现在,您只需执行
    /bash roll
    (或在
    chmod 755 roll
    之后)操作
    /roll
    ,您的左轮手枪就装载了一颗子弹。运行
    /roll
    几次,每次
    /roll
    之后,用
    cat/tmp/左轮手枪检查子弹位置

  • shoot
    命令应:
    • 将线条旋转一个位置(如在真实的左轮手枪中)
    • 并旋塞液压锤-例如,检查第1行的值
  • 这将输出如下内容:

    Click
    Click
    Boom
    Click
    Click
    ... and forever ...
    Click
    
    变体B-在每次射击之间滚动(例如,用1颗子弹重新装填)

    while :
    do
        ./roll
        ./shoot
    done
    
    这将打印例如:

    Click
    Click
    Boom
    Boom
    Click
    Click
    Click
    Boom
    Click
    Click
    Click
    Click
    Click
    Click
    Click
    Click
    Click
    Boom
    Click
    ... etc ...
    
    此外,您还可以使用另一个命令扩展/修改脚本:
    load
    ,并将您的左轮手枪重新定义为:

    • 加载
      -将一个(或多个)子弹加载到气缸中
    • 滚转
      -将按随机位置数旋转气缸(但不重新加载子弹)-例如,在发射子弹后,滚转将仅旋转空气缸
    • 射击
      -射击(无需修改)

    将一个阵列从0随机洗牌到5,仅在0时鸣响。@ace:这仍然会导致相同的问题,阵列每次洗牌都会回到相同的情况。在两次射击之间,你会滚动左轮手枪的气缸吗?你只能滚动一次并竖起锤子直到它射击为止(例如,你是对的-最多6次),或者你将在两次射击之间滚动,并且幸运的是,你可以射击6次以上。
    ./roll
    while :
    do
        ./shoot
    done
    
    Click
    Click
    Boom
    Click
    Click
    ... and forever ...
    Click
    
    while :
    do
        ./roll
        ./shoot
    done
    
    Click
    Click
    Boom
    Boom
    Click
    Click
    Click
    Boom
    Click
    Click
    Click
    Click
    Click
    Click
    Click
    Click
    Click
    Boom
    Click
    ... etc ...