68830
コマンドの結果を引数にしてコマンドを実行する alias を書きたいです

具体的には特定の name のついた ec2 に SSM ログインするコマンドを書きたいので

```

    aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | select(.Tags[].Value == "api") | .InstanceId'
    
```

このコマンド結果を最後につけて

```

    aws ssm start-session --target <ここに結果を入れたい>
    
```

を実行する alias を作りたいです

```

    alias api-login="aws ssm start-session --target $(aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | select(.Tags[].Value == "api") | .InstanceId')"
    
```

と定義してしまうと定義時に中身が展開されてしまって

```

    api-login='aws ssm start-session --target i-xxxxxxxx'
    
```

となって値が固定されてしまいます  
コマンド実行時に内側も実行したいのですがどう書けばいいでしょうか
CC BY-SA 4.0
2020-07-22T04:45:07.003
68812
2020-07-23T04:13:36.270
2020-07-23T04:05:14.417
5008
question
shellscript zsh
alias の中で動的に実行したコマンド結果を使いたい
alias を使いたければ、ダブルクォートではなくシングルクォートで囲えば良いです。`$(...)`
の中身は、ダブルクォートだと文字列として評価される際に展開されますが、シングルクォートだとコマンドとして評価される際に展開されます。

ですが、このくらい複雑になるのであれば alias ではなくて shell の関数にする方がコードに説明がつけられて見やすくなりそうです。

```

    api-login () {
        local instance_id="$(aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | select(.Tags[].Value == "api") | .InstanceId')"
        aws ssm start-session --target "${instance_id}"
    }
    
```
CC BY-SA 4.0
2020-07-22T11:28:26.933
68830
2020-07-23T04:13:36.270
2020-07-23T04:13:36.270
19110
19110
68812
answer
Shellじゃないのでオフトピかもしれませんが、[awscli-aliases](https://github.com/awslabs/awscli-
aliases) を使って AWSCLIのAliasにする方法もあります。設定ファイルは `$HOME/.aws/cli/alias` にあるので
`$HOME/.aws/config` などと一緒に管理しておけば環境移行も楽だと思います。

```

    api-login =
      !f() {
        target=$(aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | select(.Tags[].Value == "api") | .InstanceId')
        aws ssm start-session --target $target
      }; f
    
```

実行例

```

    $ aws api-login
    
    Starting session with SessionId: xxxxxx-00000000000000000
    sh-4.2$ whoami
    ssm-user
    
```
CC BY-SA 4.0
2020-07-22T17:30:05.707
68844
2020-07-23T04:07:32.497
2020-07-23T04:07:32.497
5008
5008
68812
answer
ちなみにAWS CLIですが

```

    aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | select(.Tags[].Value == "api") | .InstanceId'
    
```

は`jq`を使わなくても

```

    aws ec2 describe-instances --filters Name=tag-value,Values=api --query Reservations[*].Instances[*].[InstanceId] --output text
    
```

と書けますし、タグ名をきちんと指定すると

```

    aws ec2 describe-instances --filters Name=tag:タグ名,Values=api --query Reservations[*].Instances[*].[InstanceId] --output text
    
```

と書けます。
CC BY-SA 4.0
2020-07-22T22:34:09.053
68846
2020-07-22T22:34:09.053
4236
68812
answer