2016-09-09 44 views
3

我需要创建一个集成脚本来设置一些环境变量,使用wget下载文件并运行它。是否可以编写一个在bash/shell和PowerShell中运行的脚本?

挑战在于它需要是可以在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 

这是在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 

所以我想如果不知何故这两个脚本可以合并,并成功地在任何平台上运行?

我一直在试图找到一种方法,把它们放在同一个脚本中,并让bash和PowerShell.exe忽略错误,但一直没有成功。

任何猜测?

+2

你看过这个吗? http://stackoverflow.com/questions/17510688/single-script-to-run-in-both-windows-batch-and-linux-bash – idjaw

+1

你可以使用PowerShell v6-alpha –

+1

哇,如果PowerShell v6可以做到这一点,这将是令人印象深刻的。随着bash提供最新版本的Windows 10,可能会解决您的问题吗? –

回答

7

这是可能的;我不知道它是如何兼容的,但PowerShell将字符串视为文本,并最终显示在屏幕上,Bash将它们视为命令并尝试运行它们,并且都支持相同的函数定义语法。所以,把函数名放在引号中,只有Bash会运行它,把“exit”放在引号中,只有Bash会退出。然后编写PowerShell代码。

注意:这是有效的,因为两个shell的语法都是重叠的,并且脚本很简单 - 运行命令并处理变量。如果您尝试使用任何一种语言的更高级脚本(如果/然后,切换,大小写等),则另一个脚本可能会抱怨。

保存为dual.ps1所以PowerShell是满意的,所以chmod +x dual.ps1猛砸要么系统上运行它

#!/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 

然后

./dual.ps1 


编辑:可以通过与不同的前缀注释的代码块,然后将具有每种语言滤出它自己的代码和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 
+1

您可以通过将'eval'语句放入一个功能块以便只有bash运行它吗? –

+0

@HarryJohnston我重试了第二个脚本,它甚至没有工作,因为我在'eval'中打破了引用。是的,把两种方法结合起来的好主意 - 甚至可以修正我改变引用的原因,所以它的效果更好 - 谢谢。(PowerShell试图评估“$(eval)”并抱怨 - 但是当它在一个没有被调用的函数中时,它不会这么做)。 – TessellatingHeckler

相关问题