当前位置: 首页 > news >正文

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

启动某个程序,再带上一堆参数,这几乎是程序员们每天必做到事情。另外再算上各种辅助程序员们的自动化脚本,辅助构建的 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 可能有一些逗比程序对 / 支持不好,更建议:

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

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

  • .NET 将混合了多个不同平台(Windows / Mac / Linux)的文件/目录的路径格式化成同一个平台下的路径 - walterlv

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

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

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

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

  • Linux Shell 中的所有需要转义的字符 - walterlv

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

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

相关文章:

  • 适合 .NET 开发者用的 GitHub Actions(时不时更新)
  • 在 CMD 里根据进程名杀掉进程
  • 在 PowerShell 里根据进程名杀掉进程
  • 在制作多框架项目的 NuGet 包时应该注意的问题(buildMultiTargeting TargetFrameworks)
  • 专业团队:推荐一个网站,生成巨幅文字注释
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • 通过设置启用 Visual Studio 默认关闭的大量强大的功能提升开发效率
  • 使用 SetWindowCompositionAttribute 来控制程序的窗口边框和背景(可以做 Acrylic 亚克力效果、模糊效果、主题色效果等)
  • input 不能为空 js_我用JS刷LeetCode | Day 9 | Implement strStr()
  • 宝塔同时安装苹果cms海洋cms_maccms安装了后接下来做什么?
  • hive 修改表的存储格式_Hive存储格式
  • mac redis 链接_2018 MAC下安装Redis和Redis可视化工具RDM并连接Redis
  • python的lib文件夹在哪_如何导入模块中的lib文件夹
  • heidisql连接不是本地_本地备份与云备份:选择您的备份计划
  • ibaties 更新 数据类型不一致_关于Python 3.9,那些你不知道的事
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • ES6核心特性
  • EventListener原理
  • in typeof instanceof ===这些运算符有什么作用
  • JDK 6和JDK 7中的substring()方法
  • React as a UI Runtime(五、列表)
  • ReactNative开发常用的三方模块
  • Vue 动态创建 component
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 面试遇到的一些题
  • 前端技术周刊 2019-01-14:客户端存储
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 三分钟教你同步 Visual Studio Code 设置
  • 想写好前端,先练好内功
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​马来语翻译中文去哪比较好?
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (java)关于Thread的挂起和恢复
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (转)linux 命令大全
  • (转)详解PHP处理密码的几种方式
  • .Net Redis的秒杀Dome和异步执行
  • .NET 指南:抽象化实现的基类
  • .NET构架之我见
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • ::
  • [20171102]视图v$session中process字段含义
  • [autojs]逍遥模拟器和vscode对接
  • [C/C++]数据结构 堆的详解
  • [C++] 默认构造函数、参数化构造函数、拷贝构造函数、移动构造函数及其使用案例
  • [C++]C++入门--引用