【问题标题】:How to automatically install a bash script globally in the system using the $PATH variable? Or rewrite the script to node如何使用 $PATH 变量在系统中全局自动安装 bash 脚本?或者重写脚本到node
【发布时间】:2023-01-18 03:41:23
【问题描述】:

例如,我有一个脚本来创建网站的本地副本(哪个脚本并不重要,我以这个脚本为例)

#!/usr/bin/env bash

set -Eeuo pipefail
trap cleanup SIGINT SIGTERM ERR EXIT

VER="1.0.0"

script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)

usage() {
  cat <<EOF
  
Copysite  v.$VER

Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-v] [--verbose] -d ./Directory -u example.com

Program based on GNU Wget - designed to create a complete local copy of the site while maintaining the file structure

+---------------------------------------+
| Autor    | fftcc                      |
| License  | GNU GPL v3                 |
| Website  | ff99cc.art                 |
| E-mail   | me@ff99cc.art              |
| Git      | codeberg.org/fftcc         |
| Keyoxide | keyoxide.org/me@ff99cc.art |
+---------------------------------------+

Available options:

-h, --help      Print this help and exit
-v, --version   Print version
--verbose       Print script debug info
-d, --dir       Target directory (by default current directory if no parameter value is passed)
-u, --url       Website address
EOF
  exit
}

ver() {
  cat <<EOF
$VER
EOF
  exit
}

cleanup() {
  trap - SIGINT SIGTERM ERR EXIT
}

msg() {
  echo >&2 -e "${1-}"
}

wget_fn() {
  wget --mirror -p --html-extension --base=./ -k -P "${dir-}" "${url-}"
}

die() {
  local msg=$1
  local code=${2-1} # default exit status 1
  msg "$msg"
  exit "$code"
}

parse_params() {

  while :; do
    case "${1-}" in
    -h | --help) usage ;;
    -v | --version) ver ;;
    --verbose) set -x ;;
    -d | --dir)
      dir="${2-}"
      shift
      ;;
    -u | --url)
      url="${2-}"
      shift
      ;;
    -?*) die "Unknown option: $1" ;;
    *) break ;;
    esac
    shift
  done

  args=("$@")

  # check required params and arguments
  [[ -z "${url-}" ]] && die "Missing required parameter: --url"
  return 0
}

parse_params "$@"

wget_fn ${dir} ${url}

帮助我编写一个脚本 install.sh,它将复制站点文件复制(或使用 curl 下载)到 /usr/bin/ 目录。但问题是并不是所有的系统都有/usr/bin/,路径可能不同,$PATH变量中就有这样的路径。但是这里还有一个问题,$PATH 中可能有多个路径。如何为系统选择一种全局安装应用程序的路径?

理论上,您可以使用常用的,例如/usr/bin/ 或/usr/local/bin/,但$PATH 中的路径可以手动或通过其他程序更改。或者比如在thermex中,从根目录到usr/bin目录的路径要经过很多文件夹 /data/data/com.termux/files/usr/bin 帮助我找到最通用的问题解决方案并编写脚本。

我在网上找到了以下解决方案:在主目录中创建一个 ~/bin 并将脚本放在那里。并通过 shell 配置文件将此目录添加到 $PATH 变量

PATH = "$HOME/bin"

但碰巧该脚本将仅对当前用户全局可执行,这不适合我。

如果有人有能力在 node js 上创建一个 cli-app 来帮助我用 js 重写我的脚本。这将通过 npm 确保跨平台兼容性,我会非常高兴。不幸的是,我没有在 commanderjs 或 oclif 上创建应用程序的经验,也没有时间从头开始学习这些工具。

【问题讨论】:

  • 如果有人帮我在Node js中重写脚本并解释Node与shell命令交互的基本原理,问题将得到解决,我将能够基于此解决方案重写其余脚本。

标签: node.js linux bash npm command-line-interface


【解决方案1】:

要更改所有用户的路径,您需要将命令放在 /etc/profile 目录的底部。等号之间不应该有空格。 $HOME 对于每个用户也是不同的,因此您不应该使用它,而是包括完整的直接路径。

# /etc/profile
export PATH="/path/to/my/file:$PATH"

现在您的程序应该包含在所有用户的PATH 中。

您也可以将可执行文件放在 /bin 目录中。

【讨论】:

    【解决方案2】:

    我找不到使用 $PATH 的解决方案。但是设法解决了使用 Nodejs 从任何目录跨平台和全局启动的问题(并在好心人的帮助下)

    #!/usr/bin/env node
    'use strict';
    
    const commander = require('commander');
    const { exec } = require("child_process");
    const program = new commander.Command();
    
    program
      .version("1.0.0")
      .description(`Creates a complete local copy of the site while maintaining the file structure
    
    +---------------------------------------+
    | Autor    | fftcc                      |
    | License  | GNU GPL v3                 |
    | Website  | ff99cc.art                 |
    | E-mail   | me@ff99cc.art              |
    | Git      | codeberg.org/fftcc         |
    | Keyoxide | keyoxide.org/me@ff99cc.art |
    +---------------------------------------+ `)
      .requiredOption('-u, --url <address>', 'Website address')
      .option('-p, --path <value>', 'Target directory', './');
    
    program.parse(process.argv);
    
    const options = program.opts();
    
    if (options.url) {
            exec(`wget --mirror -p --html-extension --base=./ -k -P ${options.path} ${options.url}`,{shell: '/usr/bin/bash'}, (error, stdout, stderr) => {
                if (error) {
                    console.log(`error: ${error.message}`);
                    return;
                }
                if (stderr) {
                    console.log(`stderr: ${stderr}`);
                    return;
                }
                console.log(`stdout: ${stdout}`);
            });
    }
    

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 2012-09-03
      • 1970-01-01
      • 2017-04-16
      • 2016-07-07
      • 2011-08-15
      • 2015-05-29
      相关资源
      最近更新 更多