使用多个if语句生成命令所需的语法

时间:2019-02-15 14:48:43

标签: bash

我正在编写一系列脚本来协助使用“ doctl”。 Doctl是DigitalOcean API(https://github.com/digitalocean/doctl)的CLI,通过正确的语法和/或脚本来创建该语法,Digitaltl对DigitalOcean客户而言非常有用。 我有一种方法可以完成当前的任务,但是我不能动摇的感觉是,有更好的方法可以在bash中编写以下函数。

问题/请求可以在ssh_public_ipv4函数以及ssh_private_ipv4函数中找到。在查看代码时,您将看到if语句的行越来越长。

下面是特定脚本的完整代码。一旦完成了一系列脚本,我将其称为“ easy-doctl”,我将通过我的github页面将其发布给公众。 https://github.com/hyukishi

我有一系列的if语句,以根据用户提供的输入提供函数正常执行所需的语法。必须有一种“捷径”将其写出并获得相同的结果。

#!/bin/bash
# Created by Jeffery Grantham 02/12/2019

doctl="$(command -v doctl)"
input="$1"
a1=""
a2=""
a3=""
a4=""
a5=""

# Array Function
droplet_id(){
n=0
for i in $(doctl compute droplet list --format ID)
do  ((n=n+1))
    if [[ "$i" == "ID" ]]; then
    ((n=n-1))
    fi
echo "$i" >/dev/null 2>&1
droplet[$n]=$i
done
}

while [[ "$input" != "quit" ]];
do
    clear
    echo "What would you like to do?"
    echo "1: SSH via PublicIPv4"
    echo "2: SSH via PrivateIPv4 (only for droplet to droplet connections)"
    echo "(Type quit to exit)"
    echo ""
    droplet_id
    read -rp "Enter the corresponding number and press ENTER: " input
    clear

# Functions
pause(){
    clear
    read -rp "Press ENTER to continue"
    clear
    return
}

ssh_public_ipv4(){
    $doctl compute droplet list --format ID,Name,PublicIPv4 | awk 'BEGIN{i=0} /.*/{printf "%d. % s\n",i,$0; i++}'
    read -rp "Droplet name or ID number: " a1
    while [[ "$a1" == "" ]] || [[ "$a1" == "help" ]];
    do
        $doctl compute droplet list --format ID,Name,PublicIPv4 | awk 'BEGIN{i=0} /.*/{printf "%d. % s\n",i,$0; i++}'
        read -rp "Droplet name or ID number: " a1
    done
    read -rp "User (leave blank for root): " a2
    if [[ "$a2" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2"
    fi
    read -rp "Port (leave blank for 22): " a3
    if [[ "$a3" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-port "$a3"
    fi
    if [[ "$a2" != "" ]] && [[ "$a3" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-port "$a3"
    fi
    read -rp "Path to SSH key (leave blank for default): " a4
    if [[ "$a4" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-key-path "$a4"
    fi
    if [[ "$a2" != "" ]] && [[ "$a3" != "" ]] && [[ "$a4" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-port "$a3" --ssh-key-path "$a4"
    fi
    read -rp "Do you want to enable agent fowarding? (y/n) " a5
    if [[ "$a5" == "y" ]]; then
        $doctl compute ssh "$a1" --ssh-agent-forwarding
    fi
    if [[ "$a2" != "" ]] && [[ "$a3" != "" ]] && [[ "$a4" != "" ]] && [[ "$a5" != "n" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-port "$a3" --ssh-key-path "$a4" --ssh-agent-forwarding
    fi
    clear
    $doctl compute ssh "${droplet[$a1]}"
    return
}

ssh_private_ipv4(){
    $doctl compute droplet list --format ID,Name,PublicIPv4 | awk 'BEGIN{i=0} /.*/{printf "%d. % s\n",i,$0; i++}'
    read -rp "Droplet name or ID number: " a1
    while [[ "$a1" == "" ]] || [[ "$a1" == "help" ]];
    do
        $doctl compute droplet list --format ID,Name,PublicIPv4 | awk 'BEGIN{i=0} /.*/{printf "%d. % s\n",i,$0; i++}'
        read -rp "Droplet name or ID number: " a1
    done
    read -rp "User (leave blank for root): " a2
    if [[ "$a2" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-private-ip "$a5"
    fi
    read -rp "Port (leave blank for 22): " a3
    if [[ "$a3" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-port "$a3" --ssh-private-ip "$a5"
    fi
    if [[ "$a2" != "" ]] && [[ "$a3" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-port "$a3" --ssh-private-ip "$a5"
    fi
    read -rp "Path to SSH key (leave blank for default): " a4
    if [[ "$a4" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-key-path "$a4" --ssh-private-ip "$a5"
    fi
    if [[ "$a2" != "" ]] && [[ "$a3" != "" ]] && [[ "$a4" != "" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-port "$a3" --ssh-key-path "$a4" --ssh-private-ip "$a5"
    fi
    read -rp "Do you want to enable agent fowarding? (y/n) " a5
    if [[ "$a5" == "y" ]]; then
        $doctl compute ssh "$a1" --ssh-agent-forwarding --ssh-private-ip "$a5"
    fi
    if [[ "$a2" != "" ]] && [[ "$a3" != "" ]] && [[ "$a4" != "" ]] && [[ "$a5" != "n" ]]; then
        $doctl compute ssh "$a1" --ssh-user "$a2" --ssh-port "$a3" --ssh-key-path "$a4" --ssh-agent-forwarding --ssh-private-ip "$a5"
    fi
    clear
    $doctl compute ssh "${droplet[$a1]}" --ssh-private-ip "$a5"
    return
}

if [[ "$input" == "1" ]]; then
    ssh_public_ipv4
fi

if [[ "$input" == "2" ]]; then
    ssh_private_ipv4
fi

done

就像我之前说过的那样,脚本可以按原样完美运行,但是我觉得有一种“捷径”来编写函数,这会使我拥有更加简洁的脚本。在有人说之前,我个人在终端上使用ssh,但是为了包括“ doctl”的功能,我包括了这些功能。我只是想立即解决问题,然后再通过连续的bash脚本进一步解决问题。

谢谢!

1 个答案:

答案 0 :(得分:1)

我认为您想要的是在处理用户输入时在数组中收集必要的参数。例如:

ssh_public_ipv4 () {
    while true; do
        $doctl compute droplet list --format ID,Name,PublicIPv4 | awk 'BEGIN{i=0} /.*/{printf "%d. % s\n",i,$0; i++}'
        read -rp "Droplet name or ID number: " a1
        [[ ${a1:-help} != help ]] && break
    done

    ssh_args=()

    read -rp "User (leave blank for root): " a2
    [[ -n "$a2" ]] && ssh_args+=(--ssh-user "$a2")

    read -rp "Port (leave blank for 22): " a3
    [[ -n "$a3" ]] && ssh_args+=(--ssh-port "$a3")

    read -rp "Path to SSH key (leave blank for default): " a4
    [[ -n "$a4" ]] && ssh_args+=(--ssh-key-path "$a4")

    read -rp "Do you want to enable agent fowarding? (y/n) " a5
    [[ "$a5" == "y" ]] && ssh_args+=(--ssh-agent-forwarding)

    $doctl compute ssh "$a1" "${ssh_args[@]}"

    clear
    $doctl compute ssh "${droplet[$a1]}"
}

如果a2为空,则--ssh-user选项不会添加到数组中。

可以使用预期的默认值无条件添加一些具有清晰默认值的选项。例如:

read -rp "User (leave blank for root): " a2
ssh_args+=(--ssh-user "${a2:-root}")

如果设置了值且不为null,则${name:-default}格式将扩展为$name;否则,它将扩展为default