LINUX.ORG.RU

Удалить последний аргумент в shell

 ,


0

2

Внутри скрипта на «чистом shell» (не bash) нужно передать в функцию все позиционные аргументы кроме последнего. Количество аргументов может меняться. Кто подскажет как удалить последний аргумент.
В bash я бы просто вызвал функцию с аргументом ${@:1:$#-1}, но в shell это не работает. Под «чистым shell» имеется ввиду dash, так как debian.

Ответ на: комментарий от SyntaxError

Нет возможность проверить на dash. Но в bash работает это:

$ cat ./args.sh
#!/bin/sh

fn()
{
        echo -n "Arguments ($#):"
        while [ $# -gt 0 ]; do
                echo -n " '$1'"
                shift
        done
        echo
}

fn "${@:1:$(($#-1))}"

$ ./args.sh "one" "two two" "three three" "four four"
Arguments (3): 'one' 'two two' 'three three'

Kroz ★★★★★
()
Ответ на: комментарий от SyntaxError

... то у ТС'а будут проблемы с именами с пробелами

Не будет, так как использую «$@»

Только ты потом всё склеиваешь в одну строку.
И удаляешь ты первый аргумент, а не последний.

Ты б запустил бы то, что написал:

$ cat ./args.sh
#!/bin/sh

fn()
{
        echo -n "Arguments ($#):"
        while [ $# -gt 0 ]; do
                echo -n " '$1'"
                shift
        done
        echo
}

# fn "${@:1:$(($#-1))}"

ARGS=
while [ $# -gt 1 ]; do
        shift
        ARGS="$ARGS $1"
done

fn $ARGS

$ ./args.sh "one" "two two" "three three" "four four"
Arguments (6): 'two' 'two' 'three' 'three' 'four' 'four'

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 2)
Ответ на: комментарий от SyntaxError

Не работает, так как это «башизм»

Значит не судьба.
Значит расскажите дебиановцам что такое нормальный shell.

Kroz ★★★★★
()

Ну нате:

#!/bin/ash

foo() {
        echo "args=$# $@"
}

foo_without_last_arg() {
        local n=1
        local sa
        while [ $n -lt $# ]; do
                eval "local a_$n=\$$n"
                sa="$sa \"\$a_$n\""
                n=$(($n+1))
        done
        eval "set --$sa"
        foo "$@"
}

foo_without_last_arg
foo_without_last_arg a1
foo_without_last_arg a1 a2
foo_without_last_arg a1 a2 a3
foo_without_last_arg "a1 x" "*" '"' 4

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)

«чистом shell»

Ущербный → «чистый». Спасибо, надо запомнить.

так как debian

В Дебиане есть и ГНУ Баш, и много чего еще.

Zmicier ★★★★★
()
Ответ на: комментарий от legolegs

Нормальный шелл в каждом мелком скрипте и враппере - это тормоза.

Хватит уже бездумно транслировали эту ерунду.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 2)
Ответ на: комментарий от Kroz

... то у ТС'а будут проблемы с именами с пробелами

Шелло-проблемы, надо юзать bash. Он с нами уже больше 20 лет. Нет причин себя ограничивать до Bourne Shell (и бздунов тоже касается)

KennyMinigun ★★★★★
()

Не мучать себя и людей и писать скрипты на питоне уже предлагали?

anonymous
()

Не знаю, как это сделать красиво, но т.к. всё предложенное на sh совсем худое, рискну предложить такой вариант.

$ cat nolastarg 
#!/bin/sh

fn() {
        echo "Arguments ($#):"
        for arg; do
                echo $arg
        done
}

if [ $# -gt 0 ]; then
        cnt=$#
        while [ $((cnt=cnt-1)) -gt 0 ]; do
                set "$@" "$1"
                shift
        done
        shift
fi

fn "$@"
$ ./nolastarg "one" "two two" "three three" "four four"
Arguments (3):
one
two two
three three

unterwulf
()
Ответ на: комментарий от KennyMinigun

надо юзать bash. Он с нами уже больше 20 лет. Нет причин себя ограничивать до Bourne Shell (и бздунов тоже касается)

Два чая этому господину.

Kroz ★★★★★
()
Ответ на: комментарий от anonymous

Не мучать себя и людей и писать скрипты на питоне уже предлагали?

Каждой задаче - свой инструмент.
В данном случае python излишен.

Kroz ★★★★★
()
Ответ на: комментарий от KennyMinigun

Башизм, не?

Не, у ash тут проблема: он не понимает n=$((n+1)) или даже n++, хотя в busybox-ном ash я сделал чтобы понимал. let - это весьма странная команда, включающая в себя echo и сравнение на ноль в качестве результата в $?, потому почти никогда и не используется.

vodz ★★★★★
()
Ответ на: комментарий от unterwulf

Не знаю, как это сделать красиво, но т.к. всё предложенное на sh совсем худое

Тю, у вас еще хуже: меняется текущий список аргументов, медленным и многословным способом. Мой вариант на самом деле можно ещё сократить было:

#!/bin/ash

foo() {
        echo "args=$# $@"
}

foo_without_last_arg() {
        local n=1
        local sa
        while [ $n -lt $# ]; do
                sa="$sa \"\$$n\""
                n=$(($n+1))
        done
        eval "set --$sa"
        foo "$@"
}

vodz ★★★★★
()
Ответ на: комментарий от fsb4000

let это и есть башизм

Неее, let это bourne-ризм :)

vodz ★★★★★
()
Ответ на: комментарий от anonymous

а вот чего дебиан упирается не понятно

Где упирается? Пиши #!/bin/bash и говноедствуй сколько влезет.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.