Linux .BAT 到 .SH 转换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17903556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:23:49  来源:igfitidea点击:

.BAT To .SH Converting?

linuxwindowsbatch-filesh

提问by Cody Yakel

Well I've written a bat file which is used to load my pokemon backups for when I'm away from my gameboys, however I've converted to linux and I'm having issues getting the .BAT file in my exe (I've decompiled the exe back the the source) to work as a .SH and I can't really find much on how to use shell commands as the same function they would be in a BAT file :/ I would also love to know how to set the SH file to load out of the current directory AND run said program in wine.

好吧,我已经编写了一个 bat 文件,用于在我离开游戏男孩时加载我的 pokemon 备份,但是我已经转换为 linux 并且在我的 exe 中获取 .BAT 文件时遇到了问题(我我已经将 exe 反编译回源代码)以作为 .SH 工作,我真的找不到太多关于如何使用 shell 命令作为它们在 BAT 文件中使用的相同功能的信息:/我也很想知道如何使用将 SH 文件设置为从当前目录加载并在 wine 中运行所述程序。

Here is my .BAT file which works 100% perfectly under windows but refuses to run under wine or a CMD prompt portable under wine

这是我的 .BAT 文件,它在 Windows 下 100% 完美运行,但拒绝在 wine 下运行或在 wine 下可移植的 CMD 提示

`:MENU
CLS

ECHO ============= RawX GBA's =============
ECHO -------------------------------------
ECHO 1.  Pokemon Crystal
ECHO 2.  Pokemon Green
ECHO 3.  Pokemon Gold
ECHO 4.  Pokemon Pikachu
ECHO 5.  Pokemon Ruby
ECHO 6.  Pokemon Chaos Black
Echo 7.  Pokemon Silver
ECHO 8.  Pokemon White (NDS)
ECHO 9.
Echo 10.
Echo 11.
Echo 12. Pokemon Black (NDS)
ECHO ==========PRESS 'Q' TO QUIT==========
ECHO.
color fc

SET INPUT=
SET /P INPUT=Please select a number:

IF /I '%INPUT%'=='1' GOTO Selection1
IF /I '%INPUT%'=='2' GOTO Selection2
IF /I '%INPUT%'=='3' GOTO Selection3
IF /I '%INPUT%'=='4' GOTO Selection4
IF /I '%INPUT%'=='5' GOTO Selection5
IF /I '%INPUT%'=='6' GOTO Selection6
IF /I '%INPUT%'=='7' GOTO Selection7
IF /I '%INPUT%'=='8' GOTO Selection8
IF /I '%INPUT%'=='9' GOTO Selection9
IF /I '%INPUT%'=='10' GOTO Selection10
IF /I '%INPUT%'=='11' GOTO Selection11
IF /I '%INPUT%'=='12' GOTO Selection12
IF /I '%INPUT%'=='Q' GOTO Quit

CLS

ECHO ============INVALID INPUT============
ECHO -------------------------------------
ECHO Please select a number from the Main
echo Menu [1-9] or select 'Q' to quit.
ECHO -------------------------------------
ECHO ======PRESS ANY KEY TO CONTINUE======

PAUSE > NUL
GOTO MENU

:Selection1

:1
".\VisualBoyAdvance.exe"  ".\Pokemon Crystal.zip"
goto menu

:Selection2

:2
".\VisualBoyAdvance.exe"  ".\Pokemon Green.zip"
goto menu

:Selection3

".\VisualBoyAdvance.exe"  ".\Pokemon Gold.zip"
goto menu

:Selection4

".\VisualBoyAdvance.exe"  ".\Poke'mon Pikachu.zip"
goto menu

:Selection5

".\VisualBoyAdvance.exe"  ".\Pokemon Ruby.zip"
goto menu

:Selection6

".\VisualBoyAdvance.exe"  ".\Pokemon - Chaos Black.zip"
goto menu

:Selection7

".\VisualBoyAdvance.exe"  ".\Pokemon Silver.zip"
goto menu


:Selection8

".\desmume.exe"  ".\PokeWhite.zip"
goto menu

:Selection12

".\desmume.exe"  ".\PokeBlack.zip"
goto menu






:Quit
CLS

ECHO ==============THANK YOU===============
ECHO -------------------------------------
ECHO ======PRESS ANY KEY TO CONTINUE======

PAUSE>NUL
EXIT`

回答by Warren Young

The conversion to Bourne shell is pretty straightforward:

转换为 Bourne shell 非常简单:

  1. Add #!/bin/shor similar as the first line, to tell Linux which interpreter to use. Unlike on Windows, there's more than one command shell, and more script interpreters than just shells besides.

  2. The equivalent of the cmd.execommand CLSis clearon Linux.

  3. Linux is case-sensitive, so all your ECHOs have to be lowercase. If I'd kept your IFstatements in the translated version, they'd have to be lowercase, too.

  4. echoin shell scripts doesn't just print everything literally to the end of the line, as in cmd.exe. Bourne shell is a much richer language: it can apply meaning to what appears after a command before sending it to the command. In your code, the single quotes (') and multiple spaces won't survive this command processing.

    To avoid problems of this sort, I've double-quoted all of your echostrings. I could have done it selectively, double-quoting only the problem strings, but chose to double-quote everything for consistency. I don't want you to get the mistaken idea that echoin Bourne shell requiresthe double-quotes.

    If I wasn't interested in keeping the translation simple, so you can see more 1:1 correspondences between batch files and shell scripts, I'd replace the two big blocks of echocommands with a heredoc.

  5. echo.is just echoin Bourne shell. You don't need the dot in Bourne shell because echoin Bourne shell isn't overloaded to turn command echoing on and off, as with ECHO ON/OFFin cmd.exe. (Bourne shell does have a similar feature, enabled via set -x.)

  6. It is possible to get colored output in Bourne shell, but there is no simple built-in command for it as in cmd.exe. If you want pretty colored menus, you can replace much of the code in this script with a call to dialog(1).

  7. You use readto get input in a shell script; setdoes other things.

  8. There is no gotoin Bourne shell. We don't need it, because Bourne shell has decent control structures. I think a casestatementexpresses the intent of your inner selection code, and an infinite whileloopexpresses the outer "keep doing this until they hit q" scheme.

  9. I don't see how code flow gets to your "press any key to continue" bit at the end, so I removed it. If I'm wrong, the rough equivalent of PAUSEis read -n 1 -s.

  10. I have changed the calls to the external programs, dropping the .exeand changing .\to ./to match the way things are done on Linux. You still need to come up with Linux equivalents of VisualBoyAdvance.exeand desmume.exe.

  1. 添加#!/bin/sh或类似于第一行,告诉 Linux 使用哪个解释器。与 Windows 不同的是,除了 shell 之外,还有不止一个命令外壳和更多的脚本解释器。

  2. 在相当于cmd.exe命令CLSclear在Linux上。

  3. Linux 区分大小写,所以你所有的ECHOs 都必须是小写的。如果我将您的IF陈述保留在翻译版本中,它们也必须是小写的。

  4. echo在 shell 脚本中不只是将所有内容逐字打印到行尾,如cmd.exe. Bourne shell 是一种更丰富的语言:它可以在将命令发送到命令之前对命令后面出现的内容应用含义。在您的代码中,单引号 ( ') 和多个空格将无法在此命令处理中保留下来。

    为避免此类问题,我对您的所有echo字符串都加了双引号。我本可以有选择地完成它,只双引号有问题的字符串,但为了一致性选择双引号。我不想让您误以为echo在 Bourne shell 中需要双引号。

    如果我对保持翻译简单不感兴趣,因此您可以看到批处理文件和 shell 脚本之间更多的 1:1 对应关系,我会用heredoc替换这两个大echo命令块。

  5. echo.只是echo在 Bourne shell 中。您不需要 Bourne shell 中的点,因为echo在 Bourne shell 中没有重载来打开和关闭命令回显,就像ECHO ON/OFFin 一样cmd.exe。(Bourne shell 确实有一个类似的功能,通过set -x.

  6. 可以在 Bourne shell 中获得彩色输出,但没有像cmd.exe. 如果你想要漂亮的彩色菜单,你可以用调用来替换这个脚本中的大部分代码dialog(1)

  7. 您用于read在 shell 脚本中获取输入;set做其他事情。

  8. gotoBourne shell 中没有。我们不需要它,因为 Bourne shell 有不错的控制结构。我认为一个case语句表达了你内部选择代码的意图,而一个无限while循环表达了外部“继续这样做直到他们命中q”方案。

  9. 我没有看到代码流最后如何到达您的“按任意键继续”位,因此我将其删除。如果我错了,大致相当于PAUSEread -n 1 -s

  10. 我已经改变了对外部程序,丢弃的呼叫.exe和更改.\./的东西在Linux上做的方式相匹配。你仍然需要拿出的Linux对应VisualBoyAdvance.exedesmume.exe

The result looks something like this:

结果如下所示:

#!/bin/sh
clear

while true do
    echo "============= RawX GBA's ============="
    echo "-------------------------------------"
    echo "1.  Pokemon Crystal"
    echo "2.  Pokemon Green"
    echo "3.  Pokemon Gold"
    echo "4.  Pokemon Pikachu"
    echo "5.  Pokemon Ruby"
    echo "6.  Pokemon Chaos Black"
    echo "7.  Pokemon Silver"
    echo "8.  Pokemon White (NDS)"
    echo "9."
    echo "10."
    echo "11."
    echo "12. Pokemon Black (NDS)"
    echo "==========PRESS 'Q' TO QUIT=========="
    echo

    echo -n "Please select a number: "
    read input

    case $input in
        1)
            ./VisualBoyAdvance "Pokemon Crystal.zip"
            ;;

        2)
            ./VisualBoyAdvance "Pokemon Green.zip"
            ;;

        # etc.

        q)
            clear
            exit

        *)
            clear
            echo "============INVALID INPUT============"
            echo "-------------------------------------"
            echo "Please select a number from the Main"
            echo "Menu [1-12] or select 'Q' to quit."
            echo "-------------------------------------"
            echo "======PRESS ANY KEY TO CONTINUE======"
    esac
done