如何在不使用“sh”或“bash”命令的情况下运行 shell 脚本?

Posted

技术标签:

【中文标题】如何在不使用“sh”或“bash”命令的情况下运行 shell 脚本?【英文标题】:How do I run a shell script without using "sh" or "bash" commands? 【发布时间】:2012-02-05 11:42:38 【问题描述】:

我有一个 shell 脚本,我想在不使用“sh”或“bash”命令的情况下运行它。例如:

代替:sh script.sh

我要使用:script.sh

我该怎么做?

附: (i) 我很少使用 shell 脚本,我尝试阅读有关别名的信息,但我不明白如何使用它们。

(ii) 我还阅读了有关将脚本与 PATH 变量中的另一个文件链接的内容。我正在使用我的大学服务器,但我无权在这些位置创建文件。

【问题讨论】:

答案表明如何使脚本可执行,但似乎没有涵盖如何使其可访问。为此,为自己创建一个 bin 目录 - $HOME/bin - 如果您还没有,请将其添加到您的 PATH(靠近前面)。将要直接执行的脚本(和任何其他程序)放在此处,无需在此处指定路径名,也无需在此处指定符号链接到实际程序所在的位置。 按照下面的答案,删除“.sh”,您可以重命名文件:mv example.sh example,然后example 应该可以自己工作。 【参考方案1】:

在文件顶部添加“shebang”:

#!/bin/bash

并使您的文件可执行 (chmod +x script.sh)。

最后修改你的路径,添加你的脚本所在的目录:

export PATH=$PATH:/appropriate/directory

(通常,您需要$HOME/bin 来存储您自己的脚本)

【讨论】:

您好,感谢您的回复。我试过了。现在我可以在没有“sh”命令的情况下运行它。但是我仍然必须在命令前加上我不想使用的“./”。 :) 查看有关路径的 cmets。您需要将脚本放在必须附加到 PATH 的目录中。 它在我的情况下不起作用。但source script.sh 工作正常,或者更确切地说是source <filename_without_any_extension_type> source ./my-cool-script(或. ./my-cool-script)将使用脚本中定义的任何变量污染当前的shell会话。除非您想通过设置环境变量、更改目录等显式修改 shell 会话,否则不应使用源。否则可能会导致非常可怕的错误,因为一个脚本执行的变量,如果通过源完成,可能会影响另一个脚本执行。 如果您确定脚本文件夹在 PATH 中,并且没有./ 仍然无法工作,那么您可能会遇到名称冲突。尝试重命名。【参考方案2】:

这些是直接使用脚本名称的先决条件:

    在最顶部添加 shebang 行 (#!/bin/bash)。 使用chmod u+x scriptname 使脚本可执行(其中scriptname 是您的脚本名称)。 将脚本放在/usr/local/bin 文件夹下。 注意:我建议将其放在/usr/local/bin 下,因为该路径很可能已经添加到您的PATH 变量中。 仅使用脚本名称scriptname 运行脚本。

如果您无权访问/usr/local/bin,请执行以下操作:

    在你的主目录中创建一个文件夹并将其命名为bin

    在您的主目录上执行ls -lA,以识别您的shell 正在使用的启动脚本。它应该是.profile.bashrc

    确定启动脚本后,添加以下行:

    PATH="$PATH:$HOME/bin"
    

    添加后,获取启动脚本或注销并重新登录。

    要获取源代码,请输入.,后跟一个空格,然后是您的启动脚本名称,例如. .profile. .bashrc

    仅使用其名称scriptname 运行脚本。

【讨论】:

我不知道系统有什么问题。我创建了一个名为 "hello" 的新 shell 脚本,其中只有一个 "echo "hello" "。我更改了它的权限并尝试了 ./hello。它不起作用。它说- 您对启动脚本做了哪些更改? myscripts 是非常规的,您在不同的地方拼写不同(单数与复数)。更常见的安排是将其称为bin,就像系统二进制文件的目录一样。 不要在 .profile 中使用 Bash-only 语法,它与其他 shell 共享。 export PATH=value 不可移植,而是应该分成两个语句。当然,您几乎可以肯定地简单地删除 export,因为这个变量肯定已经为您提供了 exported,所以没有必要再这样做了。 @wjandrea 好倡议。我也删除了export【参考方案3】:

只要确保它是可执行的,使用chmod +x。默认情况下,当前目录不在您的 PATH 中,因此您需要将其作为 ./script.sh 执行 - 或者通过限定路径引用它。或者,如果您真的只需要 script.sh,则需要将其添加到您的 PATH 中。 (您可能无权修改系统路径,但您几乎可以肯定地修改您自己当前环境的 PATH。)这也假设您的脚本以 #!/bin/sh 之类的内容开头。

你仍然可以使用别名,它与 shell 脚本无关,而只是 shell,简单如下:

alias script.sh='sh script.sh'

这将允许您仅使用 script.sh(字面意思 - 这不适用于任何其他 *.sh 文件)而不是 sh script.sh

【讨论】:

嘿!感谢您的回复。我之前尝试过使用别名。但是什么也没发生。我将它放在“#!/usr/local/bin/bash”行之后。你觉得哪里不对? 不能在脚本中定义别名 - 它必须声明为当前环境的一部分。所以只需在 shell 提示符下运行alias 命令,然后别名就可以用来运行命令了。【参考方案4】:

在本例中,文件将被称为myShell

首先我们需要制作这个文件,我们可以通过键入以下内容开始:

sudo nano myShell

注意到我们没有添加 .sh 扩展名? 那是因为当我们从终端运行它时,我们只需要输入myShell 就可以运行我们的命令!

现在,在 nano 中,顶行必须是 #!/bin/bash,然后您可以在继续之前留下一个新行。

为了演示,我将添加一个基本的Hello World! 响应

所以,我输入以下内容:

echo Hello World!

之后我的示例应该如下所示:

#!/bin/bash
echo Hello World!

现在保存文件,然后运行以下命令:

chmod +x myShell

现在我们已经使文件可执行,我们可以使用以下命令将其移动到/usr/bin/

sudo cp myShell /usr/bin/

恭喜!我们的命令现在完成了!在终端中我们可以输入myShell,它应该是Hello World!

【讨论】:

您不应该将自己的文件放在/usr/bin 中——许多系统为此目的使用/usr/local/bin,并为操作系统保留/usr/bin 没有必要sudo chmod你自己的文件。 无需重启机器。最多你应该再次采购 我删除了sudo 之前的chmod 和重启的建议。【参考方案5】:

您必须为程序启用可执行位。

chmod +x script.sh

那么你可以使用./script.sh

您可以将该文件夹添加到您的.bashrc 文件(位于您的主目录中)的PATH 中。 将此行添加到文件末尾:

export PATH=$PATH:/your/folder/here

【讨论】:

我忘了说我已经设置了正确的权限。我使用了命令“chmod 755 script.sh”【参考方案6】:

你可以输入 sudo install (脚本名称) /usr/local/bin/(你想输入什么来执行脚本)

例如:sudo install quickcommit.sh /usr/local/bin/quickcommit 输入密码

现在可以在没有 .sh 的情况下在任何目录中运行

【讨论】:

... 前提是您之前还确保该文件对每个人都是可读和可执行的。 chmod a+x quickcommit.sh【参考方案7】:

添加 . (当前目录)到您的 PATH 变量。 您可以通过编辑 .profile 文件来做到这一点。 将以下行放入您的 .profile 文件中PATH=$PATH:. 只需确保在脚本开头添加 Shebang (#!/bin/bash) 行并使脚本可执行(使用 chmod +x <File Name>)。

【讨论】:

不要这样做。有充分的理由在您的PATH 上拥有当前目录。这使得很容易 - 特别是对于初学者 - 意外隐藏关键的系统命令,或者更糟糕的是,被欺骗执行其他人的命令。【参考方案8】:

这是我的备份脚本,它将为您提供想法和自动化:

服务器:Ubuntu 16.04 php: 7.0 Apache2、mysql 等...

# Make Shell Backup Script - Bash Backup Script
    nano /home/user/bash/backupscript.sh
        #!/bin/bash
        # Backup All Start
        mkdir /home/user/backup/$(date +"%Y-%m-%d")
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_rest.zip /etc -x "*apache2*" -x "*php*" -x "*mysql*"
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_apache2.zip /etc/apache2
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_php.zip /etc/php
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_mysql.zip /etc/mysql
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/var_www_rest.zip /var/www -x "*html*"
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/var_www_html.zip /var/www/html
        sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/home_user.zip /home/user -x "*backup*"
        # Backup All End
        echo "Backup Completed Successfully!"
        echo "Location: /home/user/backup/$(date +"%Y-%m-%d")"

    chmod +x /home/user/bash/backupscript.sh
    sudo ln -s /home/user/bash/backupscript.sh /usr/bin/backupscript

将 /home/user 更改为您的用户目录并在终端上的任意位置键入:backupscript 以运行脚本! (假设 /usr/bin 在你的路径中)

【讨论】:

【参考方案9】:

在脚本前输入"#!/bin/sh"。 然后将其保存为script.sh,例如。 将其复制到$HOME/bin$HOME/usr/bin 该目录在不同的 Linux 发行版上可能不同,但它们以 'bin' 结尾并且位于主目录中 cd $HOME/bin$HOME/usr/bin 输入chmod 700 script.sh 您只需在终端上输入run.sh 即可运行它。 如果不起作用,请尝试chmod +x run.sh 而不是chmod 700 run.sh

【讨论】:

这个答案中没有从非常旧的现有答案中重述信息的部分被混淆了。【参考方案10】:

将任何文件设为可执行文件


假设您有一个名为 migrate_linux_amd64 的可执行文件,并且您希望将该文件作为“migrate”之类的命令运行

    首先从文件位置测试可执行文件:
[oracle@localhost]$ ./migrate.linux-amd64 
Usage: migrate OPTIONS COMMAND [arg...]
       migrate [ -version | -help ]

Options:
  -source          Location of the migrations (driver://url)
  -path            Shorthand for -source=file://path 
  -database        Run migrations against this database (driver://url)
  -prefetch N      Number of migrations to load in advance before executing (default 10)
  -lock-timeout N  Allow N seconds to acquire database lock (default 15)
  -verbose         Print verbose logging
  -version         Print version
  -help            Print usage

Commands:
  goto V       Migrate to version V
  up [N]       Apply all or N up migrations
  down [N]     Apply all or N down migrations
  drop         Drop everyting inside database
  force V      Set version V but don't run migration (ignores dirty state)
  version      Print current migration version

    确保您对该文件具有执行权限-rwxr-xr-x 1 oracle oinstall 7473971 May 18 2017 migrate.linux-amd64 如果没有,请运行chmod +x migrate.linux-amd64

    然后将您的文件复制到/usr/local/bin。该目录为root所有,使用sudo或切换到root并执行以下操作

sudo cp migrate.linux-amd64 /usr/local/bin
sudo chown oracle:oracle /user/local/bin/migrate.linux.amd64
    然后创建如下符号链接
sudo ln /usr/local/bin/migrate.linux.amd64 /usr/local/bin/migrate
sudo chown oracle:oracle /usr/local/bin/migrate
    最后将 /usr/local/bin 添加到您的路径或用户配置文件中
export PATH = $PATH:/usr/local/bin
    然后以“迁移”身份运行命令
[oracle@localhost]$ migrate
Usage: migrate OPTIONS COMMAND [arg...]
       migrate [ -version | -help ]

Options:
  -source          Location of the migrations (driver://url)
  -path            Shorthand for -source=file://path 
  -database        Run migrations against this database (driver://url)
  -prefetch N      Number of migrations to load in advance before executing (default 10)
  -lock-timeout N  Allow N seconds to acquire database lock (default 15)
  -verbose         Print verbose logging
  -version         Print version
  -help            Print usage

Commands:
  goto V       Migrate to version V
  up [N]       Apply all or N up migrations
  down [N]     Apply all or N down migrations
  drop         Drop everyting inside database
  force V      Set version V but don't run migration (ignores dirty state)
  version      Print current migration version

【讨论】:

【参考方案11】:

只是:

/path/to/file/my_script.sh

【讨论】:

【参考方案12】:
    使用文件属性将脚本文件设置为可执行文件 为 ~/.bashrc 中的可执行文件创建别名。 alias <alias namme> = <full script file path>' 刷新用户会话以应用它。 source ~/.bashrc

【讨论】:

为每个可执行文件添加别名不是好的做法。别名只能从交互式 shell 运行(不能从其他脚本调用或从非 shell 应用程序调用)。如果将可执行文件安装在 PATH 中的某个位置,则根本没有理由使用别名。

以上是关于如何在不使用“sh”或“bash”命令的情况下运行 shell 脚本?的主要内容,如果未能解决你的问题,请参考以下文章

在不退出的情况下运行 bash -c

如何限制 BASH 脚本的运行时间

sh 如何在不获取nohup.out的情况下使用nohup命令?

如何在不创建子外壳的情况下将命令的输出存储在变量中 [Bash <v4]

bash 脚本如何在不使用 uudecode 的情况下写出二进制文件?

Linux Shell基础