如何为传入参数的命令列表创建 alias/map

How to create an alias/map to a list of commands with arguments passed in

我不确定创建它的最佳方法是什么,但这是我想在此 shell 脚本中执行的流程。我基本上有一个 commands/cli 列表(将数据库连接字符串传递给 postgres),我想通过传递别名和另一个参数(名称)来创建快捷方式,以便我可以执行命令。

我正在尝试使用关联数组,但不确定是否可以这样做。

这是我目前所拥有的。

#!/bin/bash

set -e
set -x


declare -A cluster_to_endpoint=(
  [c01]="psql -h test-endpoint1-us-east-1.redshift.amazonaws.com -U masteruser -v v1=$NAME -p 5439 -f getTableDetails.sql"
  [c02]="psql -h test-endpoint2.us-east-1.redshift.amazonaws.com -U masteruser -v v1=$NAME -p 5439 -f getTableDetails.sql"
  [c03]="psql -h test-endpoint3.us-east-1.redshift.amazonaws.com -U masteruser -v v1=$NAME -p 5439 -f getTableDetails.sql"
)


while getopts ":c:n:" opt; do
  case $opt in
    c) cluster="$OPTARG";;
    n) name="$OPTARG";;
    *) usage
       exit 1
       ;;
  esac
done

我正在使用 getopts 来传递参数。

我想这样执行:./myscript.sh -c c01 -n foobar

我想在 macOS 上 运行 这个。

如果您想使用更新版本的 bash,请更新 shebang 以引用它,最好使用 #!/usr/local/bin/bash#!/opt/local/bin/bash,具体取决于您的包管理器。如果新的 bash 将更早出现在 PATH 中,您也可以使用 #!/usr/bin/env bash

如果您要使用系统 bash,则必须更改代码以避免关联数组。

OS X 附带的 bash 版本不支持关联数组。此版本的 bash 可作为 /bin/bash/bin/sh 使用。自己在 OS X 上安装更高版本的 bash 没有任何障碍(或使用 macports 或 homebrew)。

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.

关联数组是在版本 4 中引入的。这是因为 OS X 使用的是最新版本的 bash,即 GPL v2。

作为变通方法,您可以使用带有 case 的函数,因为您不会在运行时向地图添加新元素:

cluster_to_endpoint() {
  case "" in
    c01)
      psql -h test-endpoint1-us-east-1.redshift.amazonaws.com -U masteruser -v v1="$NAME" -p 5439 -f getTableDetails.sql
      ;;
    c02) 
      psql -h test-endpoint2.us-east-1.redshift.amazonaws.com -U masteruser -v v1="$NAME" -p 5439 -f getTableDetails.sql
      ;;
    c03)
      psql -h test-endpoint3.us-east-1.redshift.amazonaws.com -U masteruser -v v1="$NAME" -p 5439 -f getTableDetails.sql
      ;;
  esac
}