4

了解 Windows/Linux 下命令行/Shell 启动程序传参的区别,这下不用再担心 Windows 下...

 2 years ago
source link: https://blog.walterlv.com/post/typing-difference-among-shells-in-different-operating-systems.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

了解 Windows/Linux 下命令行/Shell 启动程序传参的区别,这下不用再担心 Windows 下启动程序传参到 Linux 下挂掉了

发布于 2020-04-30 09:19
更新于 2021-08-30 02:41

启动某个程序,再带上一堆参数,这几乎是程序员们每天必做到事情。另外再算上各种辅助程序员们的自动化脚本,辅助构建的 CI(持续集成)等等,程序员们在创造大量的应用程序然后调用它们。

但是,不经常跨系统玩这些的小伙伴们注意了,Windows 下的 Shell 和 Linux 下的 Shell 是有区别的!如果你不了解这些区别,很容易造成在 Windows 下编写的代码/脚本在 Linux 下无法使用的问题。

本文列举 Windows/Linux 下 Shell 的区别。


分号(;)

分号(;)在 Linux 的 Shell 中是不同命令的分割,而在 Windows 中只是一个普通的字符。

dotnet build;dotnet pack

这在 Linux 中是执行两句不同的命令,dotnet builddotnet pack。而换到 Windows 中,这变成了执行 dotnet 程序,然后传入 build;dotnet pack 这个参数。

foo --tags NET48;NETCOREAPP3_1;RELEASE

这在 Windows 下是启动 foo 程序,然后传入 NET48;NETCOREAPP3_1;RELEASE,而在 Linux 下则变成了执行三个不同的命令。后面两个显然不是命令,于是执行时会报 127 错误:Command not found。(程序执行完成退出,返回值为 127。)

如果你希望你的执行脚本跨平台,那么:

  1. 不要使用分号 ; 来尝试将两个或多个不同的命令合并成 1 行,直接执行多个命令即可。
  2. 如果命令名称或参数中存在分号,则必须使用引号 " 将它包裹起来。

Windows 下针对路径中包含空格的情况,用引号包裹路径:

"C:\Program Files\Walterlv\Foo.exe"

Linux 下,如果路径中包含空格,则有三种不同的解决策略:

# 加 \ 转义
/mnt/c/Program\ Files/Walterlv/Foo

# 加双引号
"/mnt/c/Program Files/Walterlv/Foo"

# 加单引号
'/mnt/c/Program Files/Walterlv/Foo'

可以发现,两者都有的方案是加双引号。所以,如果希望你的命令脚本跨平台使用,则应该使用双引号包裹路径。

路径分隔符

Windows 下,\/ 都是路径分隔符。Linux 下,只有 / 是路径分隔符,\ 是合理的文件名,在 Shell 中,\ 是转义字符。

虽然理论上所有路径都使用 / 可以让你的跨平台脚本在以上所有系统中正常工作,但考虑到 Windows 可能有一些逗比程序对 / 支持不好,更建议:

  • 在所有场景下生成路径字符串时使用当前平台的路径分隔符
  • 不要将某平台生成的路径分隔符直接拿到另一平台使用

关于跨平台路径分隔符的问题,我专门写了一篇博客,在那里可以了解更多:

其他特殊字符( ( $ { * #

在 Linux 的 Shell 中,有很多字符有特殊用途,而在 Windows Shell 中,这些字符的作用完全由被调用的应用程序来决定。

所以对于跨平台的脚本,最好尽量避免使用这些字符。

关于 Linux 下这些转义字符的用途,可以阅读我的另一篇博客:

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/typing-difference-among-shells-in-different-operating-systems.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,或者前往 CSDN 关注我的主页

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected])


Recommend

  • 54
    • helei112g.github.io 6 years ago
    • Cache

    Golang中函数传参存在引用传递吗?

    Go的函数传递详解,一篇文章搞明白Golang的值传递。 继上篇文章后,继续来探讨下面的几个问题: 函数传参中值传递、指针传递与引用传递到底有什么不一样? 为什么说 slice 、

  • 31

    从字节码看java中 this 隐式传参具体体现,也发现了 static 与 非 static 方法的区别所在! static与非static方法都是存储java的方法区。在static 方法中,没有this引用,因此无法使用当前类中所定义的变量,而非static方法则会...

  • 50
    • 掘金 juejin.im 5 years ago
    • Cache

    Vue传参一箩筐

    Vue页面、组件之间传参方式繁多,此处罗列出常用的几种方式,欢迎审阅补充。一丶路由传参这里的路由传参以编程式router.push(...)为例,声明式<router-link :to="...">与之类似。此处模拟情景为从componentsA.

  • 55
    • www.tuicool.com 4 years ago
    • Cache

    Flutter-页面跳转传参

    路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewController。所谓路由管理,就是管理页面之间如何跳转,通常也可被称为导航管理。Flut...

  • 7
    • www.zhangxinxu.com 3 years ago
    • Cache

    我是如何通过CSS向JS传参的

    by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9263 本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可...

  • 5
    • zhuanlan.zhihu.com 3 years ago
    • Cache

    Windows 后台静默跑一个命令行程序

    Windows 后台静默跑一个命令行程序红日照小池米哈游辞职。B站:红日照小池

  • 5

    V2EX  ›  程序员 有没有什么方法能让 go 写的命令行程序在 windows 上以服务的方式运行  

  • 4

    有时候想要从命令行直接结束一个程序进程,类似linux的kill命令。 那么,windows是否支持这种操作呢? 使用taskkill可以实现这个目的。 taskkill的使用方法: taskkill /? TASKKILL [/S system [/U u...

  • 4

    $router和$route的区别,路由跳转方式name 、 path 和传参方式params 、query的区别发布于 35 分钟前一、$router和$route的区别$router :...

  • 4
    • viencoding.com 1 year ago
    • Cache

    微信小程序返回上一页传参

    微信小程序返回上一页传参 2021-09-08 08:28:11  ...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK