Duk*_*gal 4 linux windows bash shell powershell
我需要创建一个集成脚本来设置一些环境变量,使用wget下载文件并运行它.
挑战在于它需要是可以在Windows PowerShell和bash/shell上运行的SAME脚本.
这是shell脚本:
#!/bin/bash
# download a script
wget http://www.example.org/my.script -O my.script
# set a couple of environment variables
export script_source=http://www.example.org
export some_value=floob
# now execute the downloaded script
bash ./my.script
Run Code Online (Sandbox Code Playgroud)
这与PowerShell中的情况相同:
wget http://www.example.org/my.script -O my.script.ps1
$env:script_source="http://www.example.org"
$env:some_value="floob"
PowerShell -File ./my.script.ps1
Run Code Online (Sandbox Code Playgroud)
所以我想知道这两个脚本是否可以合并并在任一平台上成功运行?
我一直在试图找到一种方法将它们放在同一个脚本中,并让bash和PowerShell.exe忽略错误,但没有成功.
任何猜测?
Jef*_*kin 12
(也感谢jp-huchins修复了错误true)
将其保存为your_thing.ps1在 Windows 上作为 powershell 运行,并在所有其他操作系统上作为 shell 运行。
#!/usr/bin/env sh\necho --% >/dev/null;: \' | out-null\n<#\'\n\n\n#\n# sh part\n#\necho "hello from bash/dash/zsh"\necho "do whatver you want just dont use #\xef\xbc\x9e directly"\necho "e.g. do #""> or something similar"\n# end bash part\n\nexit #>\n\n\n#\n# powershell part\n#\necho "hello from powershell"\necho "you literally don\'t have to escape anything here"\nRun Code Online (Sandbox Code Playgroud)\n<#,但它们会在 bash/shell 语言中引起问题。我们需要使用类似于 bash 的字符串"<#",但我们需要它不是 powershell 中的字符串。--%可以在不开始字符串的情况下写入单引号,例如echo --% \' blah \'将打印出\' blah \'。这很棒,因为在 shell/bash 中单引号确实会启动一个字符串,例如echo --% \' blah \'将打印出来blahecho命令<#,但在 powershell 中相同的代码完成回显命令然后启动多行注释>/dev/null到 bash 中,以便它不会--%每次都打印出来,并且我们添加到| out-nullpowershell 中,以便它不会>/dev/null;: \'每次都打印出来。语法高亮更直观地讲述故事
所有绿色的东西都会被powershell忽略(注释)
\n灰色--%是特殊的
\n| out-null是特殊的
\n白色部分只是不带引号的字符串参数\n
(即使单引号相当于"\'")
\n这<#是一个多引号的开始行注释
对于 bash 来说,情况完全不同。
\n石灰绿+下划线是命令。
\n--%这并不特殊,它只是一个参数
\n但是;很特殊
\n紫色是输出重定向
\n然后:只是标准的“不执行任何操作”shell 命令
\n然后\'启动一个在下一行结束的字符串参数
几乎没有。Powershell 确实没有缺点。Bash 警告很容易修复,而且极其罕见
\n"#>"为"#"">"\' blah #> \'更改为\' blah #\'\'> \'。#>并且由于某种原因您无法更改该评论(这就是我所说的极其罕见的情况),您实际上可以只使用#>,您只需在您的评论之后添加重新添加前两行(例如true --%等)#>评论#来删除字符串的一部分(我敢打赌大多数人甚至不知道这是 bash 功能)。下面的示例代码\n https://man7.org/linux/man-pages/man1/bash.1.html#EXPANSIONvar1=">blah"\necho ${var1#\xef\xbc\x9e}\n# ^ removes the > from var1\nRun Code Online (Sandbox Code Playgroud)\n要解决这个问题,还有其他方法可以从字符串开头删除字符,请使用它们。
\n有可能的; 我不知道这是多么兼容,但PowerShell将字符串视为文本并最终显示在屏幕上,Bash将它们视为命令并尝试运行它们,并且两者都支持相同的函数定义语法.因此,将函数名称放在引号中,只有Bash会运行它,将"exit"放在引号中,只有Bash才会退出.然后编写PowerShell代码.
NB.这是有效的,因为两个shell中的语法重叠,并且您的脚本很简单 - 运行命令并处理变量.如果您尝试使用更高级的脚本(if/then,for,switch,case等)用于任何一种语言,另一种可能会抱怨.
保存这个,dual.ps1因此PowerShell对此感到满意,chmod +x dual.ps1因此Bash将运行它
#!/bin/bash
function DoBashThings {
wget http://www.example.org/my.script -O my.script
# set a couple of environment variables
export script_source=http://www.example.org
export some_value=floob
# now execute the downloaded script
bash ./my.script
}
"DoBashThings" # This runs the bash script, in PS it's just a string
"exit" # This quits the bash version, in PS it's just a string
# PowerShell code here
# --------------------
Invoke-WebRequest "http://www.example.org/my.script.ps1" -OutFile my.script.ps1
$env:script_source="http://www.example.org"
$env:some_value="floob"
PowerShell -File ./my.script.ps1
Run Code Online (Sandbox Code Playgroud)
然后
./dual.ps1
Run Code Online (Sandbox Code Playgroud)
在任何一个系统上
编辑:您可以通过使用不同的前缀注释代码块来包含更复杂的代码,然后让每种语言过滤掉自己的代码eval(通常的安全警告适用于eval),例如使用此方法(结合Harry Johnston的建议):
#!/bin/bash
#posh $num = 200
#posh if (150 -lt $num) {
#posh write-host "PowerShell here"
#posh }
#bash thing="xyz"
#bash if [ "$thing" = "xyz" ]
#bash then
#bash echo "Bash here"
#bash fi
function RunBashStuff {
eval "$(grep '^#bash' $0 | sed -e 's/^#bash //')"
}
"RunBashStuff"
"exit"
((Get-Content $MyInvocation.MyCommand.Source) -match '^#posh' -replace '^#posh ') -join "`n" | Invoke-Expression
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1583 次 |
| 最近记录: |