関数からエイリアスを作成する

関数からエイリアスを作成する

他のサーバー用のSSHトンネルを作成するには、さまざまなエイリアスが必要です。そのうちのいくつかを教えてください:

alias tunnel_1='autossh -M 20000 -N -L 8080:localhost:8080 -N -L 9200:localhost:9200 -N -L 8090:localhost:8090 [email protected]'
alias tunnel_2='autossh -M 20000 -N -L 8000:localhost:8080 -N -L 9200:localhost:9200 -N -L 8090:localhost:8090 [email protected]'

エイリアスにこの関数を追加しました。

addPort () {
  echo "-N -L $1:localhost:$1 "
}

tunnel () {
  aliasString="autossh -M 20000 "
  for port in "${@:2}"
  do
    aliasString+=$(addPort $port)
  done
  aliasString+="$1"
  eval $aliasString
}

したがって、目的のサーバーにトンネリングするには、次のようにします。

tunnel [email protected] 8080 9000 7200

うまくいきますが、可能であればevalを使用したくありません。autosshevalを使わずに直接呼び出して正しいパラメータを提供する別の方法はありますか?

答え1

シングルシェル機能を使用します。

tunnel () {
    local host="$1"; shift
    local port
    local args

    args=( -M 20000 )

    for port do
        args+=( -N -L "$port:localhost:$port" )
    done

    autossh "${args[@]}" "$host"
}

または次の場合/bin/sh

tunnel () {
    host="$1"; shift

    for port do
        set -- "$@" -N -L "$port:localhost:$port"
        shift
    done

    autossh -M 20000 "$@" "$host"
}

どちらの関数も最初の引数を変数として抽出し、指定されたhostポート番号で構成される文字列のリストを作成します。

最後に、両方の関数はautossh与えられたリストとホストを使って呼び出されます。

答え2

aliasStringスペースを除くシェル特殊文字は含まれません。したがってeval $aliasString、、eval "$aliasString"および$aliasStringすべて同じです。これ引用符なしで変数を置き換える aliasStringワイルドカードがないため、ワード分離とワイルドカード拡張を実行します。これは単なる単語の分離です。eval "$aliasString"すべてのシェル解析と評価ステップが実行されます。スペース以外の特殊文字がないため、トークン化のみが行われます。eval $aliasString引用符のない変数置換で単語分割を実行し、単語を一緒に連結し、間にスペースを追加し、完全なシェル評価を実行して単語を再分割します。

これはこの関数を通常のshで書くより簡単な方法です。

tunnel () {
  command=$1
  shift
  for port do
    command="-N -L "$port:localhost:$port $command"
  done
  autossh -M 20000 $command
}

これは、空白のワイルドカードを含まないパラメータに対してのみ機能します。バラよりコサロナンダの答えより強力なアプローチのために。

関連するシェルエイリアスはまったくありません。

関連情報