Почему игнорируются все аргументы, кроме первого? - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь создать собственную командную строку. Например, если я наберу

. filename.sh 1 hello 2 hi 3 a 0 b

, пользовательское приглашение должно выглядеть следующим образом:

[b][hello][hi][a]$

Число 1 означает вторую позицию, а цифра 2 - третью позицию et c. Но когда я запускаю его, почему-то отображается только первая часть, например:

[][hello][][]$

И я не могу его перезаписать. Например, когда я набираю

. filename.sh 2 hi

, это должно быть [][hello][hi][]$, но вместо этого оно становится [][][hi][]$. Как решить?

#!/bin/bash

#$1 [$2] $3 [$4] $5 [$6] $7 [$8]

PS1="[][][][]$"

for i in "$*"
do

    #$1
    if [ $1 -eq 0 ]
    then
        PS1="[$2][][][]$"
    elif [ $1 -eq 1 ]
    then
        PS1="[][$2][][]$"
    elif [ $1 -eq 2 ]
    then
        PS1="[][][$2][]$"
    elif [ $1 -eq 3 ]
    then
        PS1="[][][][$2]$"


        #$3
    elif [ $3 -eq 0 ]
    then
        PS1="[$4][][][]$"
    elif [ $3 -eq 1 ]
    then
        PS1="[][$4][][]$"
    elif [ $3 -eq 2 ]
    then
        PS1="[][][$4][]$"
    elif [ $3 -eq 3 ]
    then
        PS1="[][][][$4]$"


        #5
    elif [ $5 -eq 0 ]
    then
        PS1="[$6][][][]$"
    elif [ $5 -eq 1 ]
    then
        PS1="[][$6][][]$"
    elif [ $5 -eq 2 ]
    then
        PS1="[][][$6][]$"
    elif [ $5 -eq 3 ]
    then
        PS1="[][][][$6]$"

        #7
    elif [ $7 -eq 0 ]
    then
        PS1="[$8][][][]$"
    elif [ $7 -eq 1 ]
    then
        PS1="[][$8][][]$"
    elif [ $7 -eq 2 ]
    then
        PS1="[][][$8][]$"
    elif [ $7 -eq 3 ]
    then
        PS1="[][][][$8]$"
    fi

done

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Если вы сделаете for i in "$*", значение i будет строкой 1 hello 2 hi 3 a 0 b, поэтому l oop выполняется только один раз.

Даже если вы убедились, что ваш l oop запускается более одного раза, вы все равно получите приглашение, в котором задано только одно из полей; все назначения для PS1 устанавливают только одно поле.

Вы должны создавать его динамически, например, так:

# Make sure PS1 is empty
unset PS1

# As long as we see command line parameters
while (($#)); do
    # Set array element at index of first parameter to value of second parameter
    arr[$1]=$2

    # Drop current parameters
    shift 2
done

# Iterate over array and build PS1
for i in {0..3}; do
    PS1+="[${arr[i]}]"
done

# Unset array so it doesn't stick around in environment
unset arr

PS1+='$'

Используется:

$ . prompt.bash 1 hello 2 hi 3 a 0 b
[b][hello][hi][a]$

Или с одним предоставленным элементом:

$ . prompt.bash 3 X
[][][][X]$
0 голосов
/ 19 июня 2020

Не воспринимайте аргументы как одно слово. Перебирать аргументы по два за раз.

# You can do something simpler with an array, but I'm deliberately keeping
# this POSIX-compatible.
while [ "$#" -gt 0 ]; do
    pos=$1

    case $pos in
      0) v0=$2 ;;
      1) v1=$2 ;;
      2) v2=$2 ;;
      3) v3=$2 ;;
      *) printf 'Illegal slot %d' "$pos" >&2; exit 1 ;;
    esac
    shift
    shift
done

PS1="[$v0][$v1][$v2][$v3]"
...