使用 shebang 运行的脚本无法解析别名,如何规避?

使用 shebang 运行的脚本无法解析别名,如何规避?

我的主要外壳是zsh

我正在使用适用于 Windows 的 Docker,因此docker找不到 WSL 内部,因为调用应该是docker.exe

我在网上找到的一个快速破解方法是alias docker=docker.exe,我这样做了(针对:.zshrc& .bashrc),这样,我的 CLI 调用就可以工作了。

不过,我有一个以 开头#!/usr/bin/env bash并包含对 的调用的脚本docker

bash script.sh显然,无论我使用或运行,都不会选择别名,./script.sh导致:

./script.sh: line 20: docker: command not found

有没有什么办法可以解决这个问题?

答案1

非交互式bash不会扩展别名,即使您的脚本定义了它们(直接定义或通过获取另一个文件,无论是否明确定义);除非shopt -s expand_aliases

我不知道,zsh但我认为这无关紧要。别名在日常命令行例程中很好用,但一般来说,它们不适用于脚本。您应该以与 shell 无关的方式在不使用它们的情况下解决问题。

我也不懂 WSL。下面的方法在 Linux 中很基础,应该可以。

  1. 符号链接:

    ln -s "/full/path/to/docker.exe" "/some/dir/in/your/PATH/docker"
    

    这样,您就可以docker.exe以该名称运行docker(甚至不用)任何shell。一个缺点:如果docker.exe被移动到另一个位置,那么符号链接将停止工作。您需要将其删除,然后使用 的新路径重新创建docker.exe

  2. 包装脚本:

    #!/bin/sh
    # adjust the shebang if needed
    exec docker.exe "$@"
    

    将其另存docker为 中的某个目录PATH;使文件可执行。现在,如果您运行docker,脚本将exec运行docker.exe。同样,调用docker将在任何shell,只要你的PATH变量导致dockerdocker.exe

别名通常用于“注入”一个或多个选项。虽然这不是你的情况,但让我们将答案变得更笼统。考虑一下alias ll='ls -l'。你无法创建执行此操作的符号链接。但是你可以编写一个脚本,相关行将是:

exec ls -l "$@"

答案2

您的.bashrc或您的设置使用的任何文件都应该有这样一行:[[ $- != *i* ]] && return如果它不是交互式 shell,它将中止获取资源文件。因此您的别名不会被获取,因为它们是为了方便交互。

要在 shell 脚本中使用别名,您需要获取别名文件或在脚本中定义别名。最终,这将需要更多行代码,您最好直接.exe在脚本中调用该文件。

注意:我们确实不应该将别名文件或我们的源.bashrc放入脚本中,因为它们可能会发生变化。

希望对您有所帮助。如果您还有其他问题,请告诉我。

答案3

为了实现这一点,您可以在脚本的开头添加这些行。

. ~/.bashrc # or whatever file that contains aliases defs.
shopt -s expand_aliases

然后你可以使用你的别名作为命令

对于函数有相同的限制,您需要在父 shell 中执行此操作。

export -f functionName

请记住,这一切都是为了可移植性,人们不会拥有您的别名和功能。

相关内容