Hen*_*dré 108 linux shell-script
什么时候#!/bin/bash比#!/bin/sh在 shell 脚本中更合适?
use*_*686 152
简而言之:
有几个 shell 实现了POSIX sh 规范的超集。在不同的系统上,/bin/sh可能是 ash、bash、dash、ksh、zsh 等的链接。(尽管它始终与 sh 兼容 - 永远不会是 csh 或fish。)
只要您sh只坚持使用功能,您就可以(甚至可能应该)使用#!/bin/sh并且脚本应该可以正常工作,无论它是哪个 shell。
如果您开始使用 bash 特定的功能(例如数组),您应该特别请求 bash – 因为,即使/bin/sh已经在您的系统上调用了 bash ,它也可能不会在其他人的系统上运行,并且您的脚本不会在那里运行。(当然同样适用于 zsh 和 ksh。)您可以使用shellcheck来识别 bashisms。
即使脚本仅供个人使用,您也可能会注意到某些操作系统/bin/sh在升级过程中发生了变化——例如,在 Debian 上它曾经是 bash,但后来被非常少的破折号取代。使用bashisms但#!/bin/sh突然中断的脚本。
然而:
即使#!/bin/bash不是很正确。在不同的系统上,bash 可能存在于/usr/binor/usr/pkg/bin或/usr/local/bin.
更可靠的选项是#!/usr/bin/env bash,它使用 $PATH。(虽然env工具本身也没有得到严格保证,/usr/bin/env但仍然可以在更多系统/bin/bash上运行。)
Dmi*_*yev 18
使用与您实际用于开发和调试脚本的 shell 相对应的 shebang。即,如果您的登录 shell 是bash,并且您在终端中将脚本作为可执行文件运行,请使用#!/bin/bash. 不要只是假设因为您没有使用过数组(或bash您知道的任何功能),所以您可以安全地选择您喜欢的任何 shell。shell(echo函数、循环、你的名字)之间有许多细微的差异,如果没有适当的测试是无法发现的。
考虑一下:如果您离开#!/bin/bash并且您的用户没有它,他们会看到一条明确的错误消息,例如
Error: /bin/bash not found
Run Code Online (Sandbox Code Playgroud)
大多数用户可以通过安装适当的软件包在一分钟内解决这个问题。另一方面,如果您将 shebang 替换为#!/bin/sh并在/bin/sh具有到 符号链接的系统上测试它/bin/bash,那么没有符号链接的用户bash将会遇到麻烦。他们很可能会看到一条神秘的错误消息,例如:
Error in script.sh line 123: error parsing token xyz
Run Code Online (Sandbox Code Playgroud)
这可能需要数小时才能修复,并且不知道他们应该使用哪个 shell。
您想在 shebang 中使用不同的 shell 的原因并不多。原因之一是您使用的 shell 并不普遍。另一个是sh在某些系统上获得显着更快的性能,并且您的脚本将成为性能瓶颈。在这种情况下,请使用目标 shell 彻底测试您的脚本,然后更改 shebang。
#! /bin/sh.永远不要在 shell 脚本中使用 bash(或 zsh、fish 或 ...)扩展。
您应该只编写适用于任何shell 语言实现的shell 脚本(包括与 shell 本身一起使用的所有“实用程序”程序)。这些日子里,你可以很可能采取POSIX.1-2001(不-2008)作为权威的什么外壳和实用程序能够,但是要知道,你可能有一天在港口脚本遗留系统调用(如的Solaris或 AIX),其 shell 和实用程序大约在 1992 年被冻结。
是的,认真的。
事情是这样的:Shell 是一种糟糕的编程语言。它唯一要做的就是它是每个Unix 安装都保证具有的/bin/sh唯一的脚本解释器。
这是另一件事:核心 Perl 5 解释器 ( /usr/bin/perl) 的某些迭代更可能在随机选择的 Unix 安装上可用(/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash。其他优秀的脚本语言(Python、Ruby、node.js 等——与 shell 相比,我什至将 PHP 和 Tcl 包括在该类别中)也大致与 bash 和其他扩展 shell 一样可用。
因此,如果您可以选择编写 bash 脚本,那么您可以选择使用一种并不糟糕的编程语言。
现在,简单的shell 脚本,那种只是从 cron 作业或其他东西中按顺序运行几个程序的那种,将它们保留为 shell 脚本并没有错。但是简单的 shell 脚本不需要数组或函数,[[甚至不需要。并且只有在别无选择的情况下才应该编写复杂的shell 脚本。例如,Autoconf 脚本实际上仍然是 shell 脚本。但是这些脚本必须在与正在配置的程序相关的每个化身上运行/bin/sh。这意味着他们不能使用任何扩展。这些天你可能不必关心旧的专有 Unix,但你可能应该关心当前的开源 BSD,其中一些没有安装bash默认情况下,嵌入式环境只给你一个最小的 shell 和busybox.
总之,当您发现自己需要可移植 shell 语言中没有的功能时,这表明脚本变得太复杂而不能保留 shell 脚本。改用更好的语言重写它。
| 归档时间: |
|
| 查看次数: |
34300 次 |
| 最近记录: |