最近遇到一个有趣的问题,让我搞清楚Linux如何选择当前执行脚本的shell

执行cts的的 media stress test 需要安装 android-cts-media-1.0.zip

把这个文件解开,发现有一个 copy_media.sh 脚本,就是用 adb push 向 android devices 复制文件,很简单的一个脚本,执行起来却有错

$./copy_media.sh 1920x1080

1920x1080
./copy_media.sh: 22: [: 1920x1080: unexpected operator
./copy_media.sh: 25: [: 1920x1080: unexpected operator
./copy_media.sh: 28: [: 1920x1080: unexpected operator
./copy_media.sh: 31: [: 1920x1080: unexpected operator
./copy_media.sh: 34: [: 1920x1080: unexpected operator
Usage: copy_media.sh [720x480|1280x720|1920x1080] [-s serial]
for testing up to 1280x720, copy_media.sh 1280x720
default resolution, when no argument is specified, is 480x360
copy_media.sh all will copy all the files.

但如果我用

$. copy_media.sh 1920x1080

执行就没有问题, 为何?我的猜想是:

./ 是用 /bin/sh 执行 copy_media.sh , 它比较”原始“,因此解释不了 其中的 if [ ... ] 语句.  用 . 就是在当前的 bash 下执行,所以成功了。

下面验证我猜想是否正确

我用 $env | grep SHELL输出是bash,那为何 copy_media.sh 是用 /bin/sh 执行

SHELL=/bin/bash

再看文件开始部分,真相大白,原来 copy_media.sh 指定用 /bin/sh执行

head copy_media.sh
#!/bin/sh
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software

而用 . (就是 source 命令) 绕开了 #!/bin/sh;另一种方法是删除这行,就会使用$SHELL变量执行的shell;当然改成
#!/bin/bash 也可以解决问题。

总结:

Linux 解释脚本按使用 shell 的顺序是

1)  脚本第一行中 #!指定

2) 没有指定就使用 $SHELL

而使用 . 就是在当前 shell 中执行,当然就不会关注 !#/bin/sh 中的指定了.

./ . 和#!/bin/bash 辨析Linux如何选择当前执行脚本的shell的更多相关文章

  1. [转帖]Linux /tmp目录下执行脚本失败提示Permission denied

    Linux /tmp目录下执行脚本失败提示Permission denied https://www.cnblogs.com/linyfeng/p/11087655.html 国产化的环境上 就有一个 ...

  2. Linux下设置定期执行脚本

    下面针对的是非ubuntu环境,会在文章末尾介绍ubuntu的一些区别. 在Linux下,经常需要定期的执行一些脚本从而来实现一些功能. 在Linux下我们用crontab来实现定期的执行脚本这个功能 ...

  3. UNIX/Linux系统管理技术手册(1)----脚本和shell

    1. 管道和重定向 (i) 要让第二条命令只有在第一条命令成功完成之后才执行,可以用一个 && 符号把两条命令隔开.例如: $ > /dev/null && cd ...

  4. linux设置crontab定时执行脚本备份mysql

    前言:mysqldump备份数据库命令 mysqldump -u root -psztx@2018 fengliuxiaosan > /dbbackup/fengliuxiaosan.sql## ...

  5. Linux开机启动时执行脚本的方法

    方法 1 – 使用 rc.local利用 /etc/ 中的 rc.local 文件在启动时执行脚本与命令.我们在文件中加上一行来执行脚本,这样每次启动系统时,都会执行该脚本.不过我们首先需要为 /et ...

  6. linux crontab设置定期执行脚本

    Linux下crontab命令的用法 任务调度的crond常驻命令crond 是linux用来定期执行程序的命令.当安装完成操作系统之后,默认便会启动此任务调度命令.crond命令每分锺会定期检查是否 ...

  7. Linux中计划任务执行脚本crontab-简洁版

    我使用的是ubuntu16,所以在ubuntu中一切正常,在其他linux系统中应该都差不多. 1 计划任务,crontab命令选项:     -u指定一个用户,     -l列出某个用户的任务计划, ...

  8. linux中计划任务执行脚本

    我使用的是ubuntu14.4,所以在ubuntu中一切正常,在其他linux系统中应该都差不多. 1 计划任务,crontab命令选项:     -u指定一个用户,     -l列出某个用户的任务计 ...

  9. linux shell中的 #!/bin/bash

    #!/bin/bash是指此脚本使用/bin/bash来解释执行. 其中,#!是一个特殊的表示符,其后,跟着解释此脚本的shell路径. bash只是shell的一种,还有很多其它shell,如:sh ...

随机推荐

  1. Xamarin.Android开发实践(二)

    原文:Xamarin.Android开发实践(二) 一.准备 开始学习本教程前必须先完成该教程http://www.cnblogs.com/yaozhenfa/p/xamarin_android_qu ...

  2. 数据切分——Atlas读写分离Mysql集群的搭建

    关于数据切分的原理可以参见博客: http://blog.csdn.net/jhq0113/article/details/44226789 关于Atlas的介绍可以参见博客: http://blog ...

  3. sqlite3 脚本的使用

    本来想找个专门查看数据库的工具的,后来发现脚本也非常easy,就直接用脚本了. sqlite3的脚本能够方便的查看当前数据库里的内容,使用起来事实上非常easy,这一列举一些最简单的使用方法,以后假设 ...

  4. java.text.NumberFormat使用方法

    NumberFormat 是全部数值格式的抽象基类. 该类提供了格式化和分析数值的接口. NumberFormat 也提供了确定 哪个语言环境具有数值格式以及它们名字的方法. package com. ...

  5. Xcode5 创建模板和UIView 关联XIB

    转自:http://www.cnblogs.com/china-ldw/p/3533896.html 在做ios应用开发的过程,难免遇到要创建 子view 和 自定义view的时候,归根到底,我们需要 ...

  6. Memcache 查看列出所有key方法

    参考博文: Memcache 查看列出所有key方法 1. cmd上登录memcache telnet 127.0.0.1 11211  2. 列出所有keys stats items // 这条是命 ...

  7. C语言深度剖析--volatile(转载)

    volatile关键字和const一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统,硬件或者其他线程等等.遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进 ...

  8. CodeForces 385C Bear and Prime Numbers 素数打表

    第一眼看这道题目的时候觉得可能会很难也看不太懂,但是看了给出的Hint之后思路就十分清晰了 Consider the first sample. Overall, the first sample h ...

  9. Codeforces Round #253 (Div. 2), problem: (B)【字符串匹配】

    简易字符串匹配,题意不难 #include <stdio.h> #include <string.h> #include <math.h> #include < ...

  10. 【.Net基础拾遗】适配器模式(Adapter)与多态

    今天晚上跟大家主要来讨论下适配器模式和多态,什么是适配器模式呢?先抛给大家一个问题:假设两个类Student和Teacher继承一个抽象基类Person,如何在不改动三类情况下实现多Student.T ...