V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ps1aniuge
V2EX  ›  Linux

在 Linux 中,如何以 100%兼容 bash 命令和脚本的情况下,主用 powershell

  •  
  •   ps1aniuge · 2019-06-02 15:02:07 +08:00 · 6785 次点击
    这是一个创建于 2026 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在 linux 中,如何以 100%兼容 bash 命令和脚本的情况下,主用 powershell

    ------ [概述] ------

    问:如何看待 bash,及 linux shell 脚本将来的地位,命运?
    问:powershell 在 linux 中的前景如何?
    答:
    就好像 [气泵射钉枪] 必将取代 [锤子] 一样,先进生产力必然代替落后的。
    就好像面向对象的 powershell,必然取代面向字符的 bat 那样。
    powershell 发展成熟后。以 bat,bash 为代表的,上一代面向字符串的脚本语言,面向字符串的命令,难免被边缘化。
    过几年后,开机启动脚本,特简单的脚本中,或许还残留有 bat,bash,字符串命令的身影。



    问:为什么要主用 powershell,边缘化 bash ?
    答:
    1 解决 bash 的癌症。
    2 增加功能。 [强]
    3 简化语法。 [简]
    4 速度快。 [快]
    新建万个空文本文件,linux 中的 ps,比 linux 中的 touch,快大约 10 倍
    http://tieba.baidu.com/p/5895236874

    搜并看:
    百万简单循环耗时,powershell 为 bash 的 3.4%,或者反过来说 bash 耗时是 powershell 的 28 倍。





    问:请举个例子?
    答:
    bash 有杀不死的 sleep。这本身是 bash 架构问题。
    很多 bash 难解决的问题,只要把部分代码改成,调用 ps1 脚本返回结果,就根本不存在了。



    问:在 linux 中主用 powershell 难么?
    问:在 linux 中主用 powershell 改动大么?
    答:
    不难,改动小。
    1 简单来讲,bash 中只有语法,没有命令和库。
    2 bash 只有 1%的语法功能,powershell 实现不了。这很正常,世界上没有两片叶子是完全一样的。


    问:世界上有 100%兼容 bash 的 shell 吗?
    答:
    世界上没有两片叶子是完全一样的。sh 和 bash 也不能 100%兼容。


    问:在 linux 中主用 powershell。是否需要把默认 shell,bash 替换成 powershell ?
    答:
    不需要或不建议。




    ------ [原则和流程] ------
    学用 pwoershell 语法,
    学用 powershell 库,
    在 bash 脚本中嵌入,powershell 命令或脚本。
    在 ps1 脚本中嵌入,bash 命令或脚本。
    并逐渐代用 /usr/bin/pwsh 代替 /usr/bin/bash。




    ------ [具体做法] ------

    问:如何在.ps1 脚本中,嵌入 [ 100%兼容 bash 的] shell 命令?
    答:
    =====================
    $bashcmd =
    @'
    echo '我是 bash 命令'
    # linux-command |awk yyy |sed zzz
    echo '命令中可以有单引号'
    echo "命令中可以有双引号"
    echo '如需解析变量,则用这种括号,注意头尾必须换行'
    echo '@\"'
    echo '$a'
    echo '\"@'
    '@
    $powershell 变量 = /usr/bin/bash -c $bashcmd
    #需要转义,有点不好
    =====================

    $powershell 变量 =
    @'
    echo '我是 bash 命令'
    # linux-command |awk yyy |sed zzz
    echo '命令中可以有单引号'
    echo "命令中可以有双引号"
    echo '如需解析变量,则用这种括号,注意头尾必须换行'
    echo '@"'
    echo '$a'
    echo '"@'
    '@ | /usr/bin/bash
    #不需要转义,推荐
    =====================


    问:如何在.sh 中,嵌入 powershell 脚本?
    答:
    aaa=`/usr/bin/pwsh -f xxx.ps1 -参数 1 'aaa' -参数 2 777`



    问:如何在.sh 中,嵌入 powershell 命令?
    答:
    aaa=`/usr/bin/pwsh -c "某 powershell 命令"`



    问:如何在 ssh 远程连接中,使用 powershell 对象,而不是 bash 字符串?
    问:如何让 powershell 成为默认的远程连接 shell ?
    答:
    在这个文件中 /etc/ssh/sshd_config
    添加一行:
    Subsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile

    注意:这么做,不会对你经 ssh,远程使用 bash 命令,产生任何影响!
    不影响!没影响!

    你不用手动添加,下面安装命令已经给你做好了。






    ------ [安装 linux 版 powershell ] ------

    centos7 及以上,安装 powershell:
    curl -o /etc/yum.repos.d/microsoft.repo https://packages.microsoft.com/config/rhel/7/prod.repo
    sudo yum remove -y powershell #删除旧版
    sudo yum install -y powershell
    pwsh -c 'mkdir -p "$env:HOME/.config/powershell" '
    pwsh -c 'Add-Content -Value "Set-PSReadlineOption -EditMode Windows" -LiteralPath $profile '
    pwsh -c 'Add-Content -Value "`nSubsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" -LiteralPath /etc/ssh/sshd_config '



    ubuntu1604:
    curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
    sudo curl -o /etc/apt/sources.list.d/microsoft.list https://packages.microsoft.com/config/ubuntu/16.04/prod.list
    sudo apt-get update
    sudo apt-get remove -y powershell #删除旧版
    sudo apt-get install -y powershell
    pwsh -c 'mkdir -p "$env:HOME/.config/powershell" '
    pwsh -c 'Add-Content -Value "Set-PSReadlineOption -EditMode Windows" -LiteralPath $profile '
    pwsh -c 'Add-Content -Value "`nSubsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" -LiteralPath /etc/ssh/sshd_config '


    ubuntu1804:
    curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
    sudo curl -o /etc/apt/sources.list.d/microsoft.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list
    sudo apt-get update
    sudo apt-get remove -y powershell #删除旧版
    sudo apt-get install -y powershell
    pwsh -c 'mkdir -p "$env:HOME/.config/powershell" '
    pwsh -c 'Add-Content -Value "Set-PSReadlineOption -EditMode Windows" -LiteralPath $profile '
    pwsh -c 'Add-Content -Value "`nSubsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" -LiteralPath /etc/ssh/sshd_config '



    debian9:
    sudo apt-get update
    sudo apt-get install curl gnupg apt-transport-https
    curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
    sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/microsoft.list'
    sudo apt-get update
    sudo apt-get remove -y powershell #删除旧版
    sudo apt-get install -y powershell
    pwsh -c 'mkdir -p "$env:HOME/.config/powershell" '
    pwsh -c 'Add-Content -Value "Set-PSReadlineOption -EditMode Windows" -LiteralPath $profile '
    pwsh -c 'Add-Content -Value "`nSubsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" -LiteralPath /etc/ssh/sshd_config '


    安装方法:
    https://docs.microsoft.com/zh-cn/powershell/scripting/setup/installing-powershell-core-on-linux?view=powershell-6


    ------ [终章] ------
    你是一个医院院长,来了病号,你让病号去找 [白大夫 bash ] 治病。
    但你发现 [白大夫] 治的疗效不好,这时候就应该让病号去找 [潘大夫 powershell ] 。

    怎么才能让这两个大夫 100%兼容呢?答案是嵌入。把 [白大夫] 嵌入 [潘大夫] ,或反之。

    医院里病号太多,而 [白大夫] 只会治疗 [字符串病] ,连 [布尔] 这种简单的 0,1 病都治不了。
    [潘大夫] 就不同了,不但会 [字符串] [布尔] [日期] [哈希表] 等,还会多线程。
    这时候院长你就应该让 [白大夫] 下岗,主用 [潘大夫] 为你院 996 服务~~~
    第 1 条附言  ·  2019-06-04 22:42:05 +08:00
    问:linux,*unix 发行版的儿子(默认 shell )都是谁?
    答:
    freebsd 的默认 shell=sh
    ubuntu=dash
    红帽等=bash
    osx=我不知道,但是 zsh 将继位。
    最新消息,下一个版本 osx,zsh 将是默认 shell。



    问:假如说 [默认原生自带 shell] 是亲儿子,那么 linux 有亲儿子么?
    答:没有。
    既然 linux 没有亲儿子,没有皇太子。那么 powershell 为什么不可以,坐等继位(上位)?

    此子有经天纬地之才。而 bash 老朽糊涂。再不退位将阻碍 linux 朝廷的发展。

    今日格言:
    win+bat 界,linux+bash 界,对待 powershell 的态度,就是脚本运维人进步的尺度。
    43 条回复    2020-03-22 15:27:52 +08:00
    uyhyygyug1234
        1
    uyhyygyug1234  
       2019-06-02 15:20:35 +08:00
    这感觉是癌症西医不行了,中医死马当活马医啊。。。
    qinghon
        2
    qinghon  
       2019-06-02 15:58:14 +08:00 via Android
    那么怎么解决在一个刚装什么都没有的系统里不装其他依赖的情况下运行 ps1 脚本?
    再附一个问题,对有的脚本自动不能识别需要自己手动修改脚本内容的地方如何解决?
    goreliu
        3
    goreliu  
       2019-06-02 16:03:57 +08:00 via Android   ❤️ 1
    在 Linux 下,powershell 取代 bash 基本是不可能的了,这不是时间长短的问题。不过自己感兴趣的话用用倒也可以。
    yuuko
        4
    yuuko  
       2019-06-02 16:09:05 +08:00 via Android   ❤️ 1
    linux 默认支持 powershell 么?不支持的话我为什么要用,还不如装个 nodejs
    tinytangent
        5
    tinytangent  
       2019-06-02 16:40:11 +08:00 via Android   ❤️ 2
    个人我觉得 PowerShell 连 cmd 都没完全取代,还取代 bash ……这东西不是说设计理念先进就解决一切问题的。bash 已经是事实标准一样的存在了,就算它再丑也得接着用。

    要真说取代 bash,还不如指望 Python 之类的脚本语言呢。搬出 PowerShell 未免……
    qinghon
        6
    qinghon  
       2019-06-02 16:58:50 +08:00 via Android
    @qinghon 对了,安装 powershell 好麻烦呀,有没有一键脚本?[滑稽]
    secondwtq
        7
    secondwtq  
       2019-06-02 17:03:01 +08:00   ❤️ 2
    十分建议感兴趣的同学通读楼主发言记录,充分学习楼主的 Linux 新时期 PowerShell 中心思想
    ysc3839
        8
    ysc3839  
       2019-06-02 17:08:19 +08:00 via Android
    @tinytangent PowerShell 在 Windows 上无法取代 cmd 的一个可能原因是不能直接执行脚本,好像需要改什么设置才能执行。
    skinny
        9
    skinny  
       2019-06-02 17:51:38 +08:00   ❤️ 2
    PowerShell 说真的并没有那么好用,就我在 Windows 上的体验来说是这样:
    1. 部署新版本非常麻烦,而旧版本又有各种问题
    2. 有的 Cmdlet 有 Bug (比如 Remove-Item 递归删除特定通配符名字时有问题,好像是所有版本都有这个问题,虽然可以通过组合 Get-ChildItem 解决)。
    3. 不同版本的一些行为有很大差异,但是如果你试图在高版本下用-Version 参数来测试脚本在特定版本下的运行结果,是没办法发现问题的。比如一个参数有多个 ParameterSetName 时,且有复杂的组合时,在真的 PowerShell 2.0 下不能运行,但是高版本下使用-Version 参数运行又完全正常。

    不过在 Windows 平台的一些特定场合,如果下面几点同时满足,我会选择 PowerShell:
    1. 在 Windows 7 及以上系统运行
    2. 不能或不方便下载安装额外的软件包、工具
    3. 需要一点简单的 GUI ( PowerShell 加 WPF,写简单的 Windows GUI 好用)

    至于在 Linux 下……拜托,我还不如用系统预装好的 Python ……有那功夫安装 PowerShell,还不如把时间用在安装几个 Python 包。
    skinny
        10
    skinny  
       2019-06-02 17:54:22 +08:00
    @ysc3839 需要设置运行策略,实际上感觉有点鸡肋……
    wwqgtxx
        11
    wwqgtxx  
       2019-06-02 18:05:05 +08:00   ❤️ 2
    在 linux 上用 ps,那干嘛不用 Python 写,功能强大得多,大部分系统还预装
    Dk2014
        12
    Dk2014  
       2019-06-02 18:11:46 +08:00 via Android   ❤️ 1
    看了下楼主回帖记录,民科程序员?
    Foxkeh
        13
    Foxkeh  
       2019-06-02 18:14:44 +08:00 via iPhone
    python+1 代码容易维护
    SuperMild
        14
    SuperMild  
       2019-06-02 18:17:43 +08:00 via iPhone
    既生瑜何生亮,可惜这家医院已经有一个 派大夫。
    Jirajine
        15
    Jirajine  
       2019-06-02 18:30:58 +08:00 via Android   ❤️ 3
    楼主你是 PowerShell 开发组的吗?这传销般的推广力度。。
    love
        16
    love  
       2019-06-02 18:47:11 +08:00 via Android
    竟然还有人粉 ps 的, 估计是 windows 爱好者爱屋及乌了
    hanxiV2EX
        17
    hanxiV2EX  
       2019-06-02 19:18:04 +08:00
    这...Windows 程序员也没几个会写 bat 吧...
    labnotok
        18
    labnotok  
       2019-06-02 19:20:55 +08:00 via Android
    先了解 bash/zsh/fish 的人,会有心情去用 PS ?
    diggerdu
        19
    diggerdu  
       2019-06-02 20:05:33 +08:00 via iPhone
    为啥不用 python 呢
    swsh007
        20
    swsh007  
       2019-06-02 20:28:12 +08:00 via Android
    还得 bash 好了
    ms 这个半吊子的东西还不如 cygwin
    junkun
        21
    junkun  
       2019-06-02 20:32:54 +08:00   ❤️ 1
    看到 powershell,我就想起了 plan 9。楼主提到的很多问题貌似并没人抱怨吧。
    edk24
        22
    edk24  
       2019-06-02 20:58:42 +08:00
    几乎都预装 python.... 用起来也很快捷轻松... 功能也丰富...
    geekc3t
        23
    geekc3t  
       2019-06-02 21:21:36 +08:00
    http://batsh.org 你需要这个
    churchmice
        24
    churchmice  
       2019-06-02 23:43:21 +08:00   ❤️ 1
    楼主的对比很有意思,用 cygwin 的环境能一样吗?
    直接两台机器一台 linux 用 bash,一台 windows 用 ps,看看哪个速度快
    ggicci
        25
    ggicci  
       2019-06-02 23:53:02 +08:00
    @qinghon @yuuko 看到你俩的头像,为啥有种情侣的赶脚 🤣
    yanqiyu
        26
    yanqiyu  
       2019-06-02 23:58:19 +08:00
    我这儿 pwsh 用 Get-ChildItem 就能正确显示汉字但是用 ls 就是\350\262 这种格式
    zhuangzhuang1988
        27
    zhuangzhuang1988  
       2019-06-03 00:02:09 +08:00
    ps 挺好的
    bash 编码都搞不定。
    cstj0505
        28
    cstj0505  
       2019-06-03 09:48:25 +08:00
    这是自问自答吗?
    为什么我要在 linux 下用 power shell
    snip
        29
    snip  
       2019-06-03 10:52:16 +08:00
    [root@localhost 1]# time touch test-{1..10000}.txt

    real 0m0.449s
    user 0m0.130s
    sys 0m0.318s

    有什么意义吗?
    pmispig
        30
    pmispig  
       2019-06-03 10:58:32 +08:00   ❤️ 1
    谈 shell 居然还说性能,你知道 shell 是做什么的吗
    appmanagecluster
        31
    appmanagecluster  
       2019-06-03 11:12:37 +08:00
    哈哈哈,you are a joke
    ps1aniuge
        32
    ps1aniuge  
    OP
       2019-06-03 17:11:17 +08:00
    @churchmice
    说的就是 linux
    这是一个真实的事情,挺多年了。是以前我在 win 中,用 gnuwin32 的时候遇到的。
    前两天,又遇到建立文件的事了。我就又用 centos7。3 + powershell beta 4 和 touch 对比了一下。
    性能大概 9----10 倍。



    @snip
    你这个是不慢的,不过我感觉这是晦涩的奇技淫巧。
    test-{1..10000}.txt 这句话凭啥就能行呢?

    bash 中:
    1..10000 不行。
    {1..10000}不行。
    {1..10000}.txt 不行。
    test-{1..10000}.txt 不行。
    不知道为啥遇到 touch 就展开成数组了。
    语法,展开,竟然不是由 shell 引擎实现,而是由命令实现,这很淫巧,不是吗?
    而不用 touch 展开,就像我例子中那样展开,很显然是慢的。
    james122333
        33
    james122333  
       2019-06-03 22:50:44 +08:00
    umask 077
    num=0
    time while ((++num < 10001))
    do
    : > test-$num.txt
    done

    ============================================

    readonly false=0
    readonly true=1

    abc=false

    if $abc && [[ -f test ]] ; then
    echo 1
    fi

    if [ $abc == false -a 2 -gt 0 ] ; then
    echo 2
    fi

    if ((abc && 2 > 0)) ; then
    echo 3
    fi

    $abc && echo ok || echo fail

    ============================================

    人有偏见 说什么都无用 本来不想理你
    james122333
        34
    james122333  
       2019-06-03 22:54:11 +08:00
    最后其他问题我就不废话了 愿意去了解的人就愿意
    tomychen
        35
    tomychen  
       2019-06-12 13:43:21 +08:00
    PowerShell?
    bash tsh zsh fish...xxsh 到 awk sed 有 powershell 什么事了?就算这些再不行还有几乎所有发行版 Builtin 的 perl,追到 2.4.x 也就是 redhat 6.x 的年代他还是有 perl 的,回到 Unix 里 FreeBSD 从经典到 10+(x)同样都是 Builtin perl。PS 是什么?好好,你 PS 厉害,新系统全系 Builtin Python 激进的系统都已经 Builtin py3 了.

    好,就算你 PS 威武霸气帅,我一个线上系统,是不是要跟安全组的人说,麻烦您把 FW 规则给关一下,我装个 PS,不然这系统我没法搞了...

    我码到这,把我自己都逗笑了...
    ps1aniuge
        36
    ps1aniuge  
    OP
       2019-06-12 14:11:54 +08:00
    @tomychen 他人笑我太疯癫,我笑他人不懂 shell,不是说任何人都能喷的。
    那些喷子不懂 shell,所以只会说观点(论点),说不出道理(论据)。

    你根本不懂 perl。perl 处理中文还不如 shell 呢。再说 perl,python 中有管道么?管道支持对象么?

    生产级的系统,不能联网,这种情况有,但是都可有做本地 repo,或者包呀。
    生产级的系统,不能联网,装 ps,也不能装 nginx,mysql,mogodb,etcd 等。

    多拿证据,少狂妄无知吧。

    ======================
    总有最后一公里问题。解决这个问题,唯有自行车,很灵活。

    就好像自行车那样,linux 版 powershell 几乎是你解决问题的唯一。是凤凰,飞鸽。
    那么 shell 呢?
    答:
    n 年前 shell 如 cygwin,是 win 的唯一。
    但现在 powershell 是 linux 的唯一。
    用现在的眼睛看 shell,
    你将看到一辆实心轱辘自行车,颠屁股,颠 jj。脚蹬子掉了,只是一个棍。
    这个车在以前,凤凰,飞鸽没出时,是极好的。那时 win 中只有木轮手推车。
    tomychen
        37
    tomychen  
       2019-06-12 14:14:56 +08:00
    @ps1aniuge 是的,您讲得有道理...
    ps1aniuge
        38
    ps1aniuge  
    OP
       2019-06-12 14:33:47 +08:00
    @tomychen 你还有潜力,用 2 个月 linux 版 powershell,找出缺点,系统思考后,再来喷。
    ungrown
        39
    ungrown  
       2019-09-12 15:37:13 +08:00
    @hanxiV2EX 还是会写的,用来干简单的活,挺方便,而且没有额外依赖。
    反正我主要用的还是 win 系统,win 下能用 bat 干的活我坚决不动鼠标,所以大多数自用脚本还是 bat,外加少量 py。
    ungrown
        40
    ungrown  
       2019-09-12 15:44:22 +08:00
    @ps1aniuge 管道中传对象是伪需求,对象管道不就是结构化的字节流管道吗?
    你把管道中的内容对象化,你就得从系统层面设计一整套数据结构规约,让系统中的所有程序都遵循这个规约,然后你才能够开开心心地在管道里传对象。
    然而问题是,这世上有可能存在一个万金油规约,适合所有程序间通讯时可能存在到对象类型,并足够好地解决各种性能、兼容性问题吗?
    做梦!
    linux 的设计理念是什么?每个组件把一件简单的事情做好,然后用数据流(管道)把大家串起来。管道里就应该跑字节流,至于这个字节流里面是何种数据结构这是各个程序自己的事情,这才是永不过时的设计思想。
    对象管道纯粹就是在扁平化民主团体内抢当话事人,省省吧。
    hanxiV2EX
        41
    hanxiV2EX  
       2019-09-12 18:55:36 +08:00 via Android
    @ungrown 我是说我见过的的 windows 程序员大多都只会用点鼠标,没见过几个会写 bat 的。不是说会不会去写,我也经常会在 windows 下去写 bat 或者 vbs 来自动做某些事情。
    ps1aniuge
        42
    ps1aniuge  
    OP
       2019-09-23 23:13:28 +08:00
    @ungrown 朽木。期待你有一天开窍,说“管道加对象真香”。

    dir | foreach-object { if ($_.length -gt 1mb ) { $_.Extension } }

    文件大小大于 1mb,则输出文件扩展名。
    或输出,文件修改时间,等其他也行。
    autogen
        43
    autogen  
       2020-03-22 15:27:52 +08:00
    $ck = [System.Diagnostics.Stopwatch]::StartNew()

    $pf = [System.IO.File]::CreateText($p_file)
    $ps = [System.IO.File]::CreateText($p_sql)

    $fh = [System.IO.File]::OpenText($file)
    try {
    for (;;)
    {
    $line = $fh.ReadLine()
    if ($line -eq $null) { break; }

    if ($line -like '*_02_*') {
    }
    }
    }finally {
    $fh.Close()
    }

    $pf.Close()
    $ps.Close()

    $ck.Stop()
    $ck.Elapsed`






    -------------------------------------------------------------------------
    这感觉像拿个 java/c++/vb 来和 shell 比。。。shell 直接投降吧,但是 python 可以一战
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5036 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 09:43 · PVG 17:43 · LAX 01:43 · JFK 04:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.