LINUX.ORG.RU

Несколько вопросов по Bash

 ,


0

1

Здравствуйте, у меня есть несколько вопросов по Sh. Либо я проглядел, либо в мануалах этого не написано.

1 [решено]. Как узнать и передать все аргументы, начиная с n’ого, если известен n?
Допустим, у меня есть скрипт ./script, который должен принять переданные ему аргументы и если 1 аргумент – arg, то программе prog должны передаться все аргумены, начиная со второго, чтобы она обработала. Например, если я вызвал ./script arg second third, то программа prog должна получить second third. Возможно ли это?

2 [решено]. Хотелось бы сделать моментальную отправку нажатий клавиш. То есть, при нажатии одной клавиши выполнялась бы запись этой буквы в переменную, без нажатия Ret. Можно ли так сделать?

3 [решено]. Как узнать номер терминала и настоящий ли он? Просто надо сделать так, чтобы в ядерной консоли №1 через один и тот же скрипт запускалась программа prog1, в ядерной консоли №2 открывался скрипт script2, а в псевдо-терминалах открывалась программа prog2. [solved]

upd. 4. У меня есть скрипт. Мне нужно прочитать все аргументы, начиная с второго. И нужно записать один и тот же текст во все файлы, перечисленные в этих аргументах.
Например, ./script arg second third. Текст должен быть записан в файлы second и third.
Это возможно?

Спасибо за существующие ответы и за последующие. За тупняк извиняюсь.



Последнее исправление: zagatov_lev (всего исправлений: 3)

Первое:

#!/usr/bin/env bash
echo "!!! $@ ???"
./prog "$@"
Вот так можно пропустить аргументы насквозь, а echo это чтобы посмотреть что же именно проходит к программе prog

https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-argume... - вот тут можно посмотреть как перечислить все аргументы в скрипте, и пропустить всё что было до n-го аргумента, там в условие while пиши свой n

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)

Можно вот так

vp@localhost ~ $ ./script.sh arg secong third
secong third
vp@localhost ~ $ ./script.sh first secong third
first secong third
vp@localhost ~ $ cat script.sh 
if [ "$1" == "arg" ]; then
    echo "${@:2}"
else
    echo $*
fi
vvvvvvvv
()
for a; do shift; [[ $a = arg ]] && break; done; prog "$@"

read -n1 var
vodz ★★★★★
()

2. Хотелось бы сделать моментальную отправку нажатий клавиш. То есть, при нажатии одной клавиши выполнялась бы запись этой буквы в переменную, без нажатия Ret. Можно ли так сделать?

$ read -n 1 -s A; read -n 10000 -t 0.1; echo "'$A'"


Второй read нужен для очистки буфера на случай если одна клавиша - несколько символов, например, стрелки, F1..F12 и т. п.

https://sites.google.com/site/bashhackers/commands/read
https://superuser.com/questions/276531/clear-stdin-before-reading

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

Не нашел, тыкните носом, пожалуйста

Это не может быть, ибо если это документация, то там и описано, что означает каждая специальная переменная, и совершенно точно там не будет в точности одинакового текста для $* так и для $@

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

Извините, пожалуйста, но после прочтения мануалов я все-таки не понял разницу.

Без кавычек $* и $@ - одно и тоже, в двойных кавычках — «$*» формирует одну строку с разделителями из первого символа в переменной $IFS, а «$@» формирует набор строк $# штук из $1 $2 и так далее.

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

«$@» формирует набор строк $# штук из $1 $2 и так далее

а какой между ними разделитель, если, например, echo "$@"?
и ещё не подскажешь, как одной командой printf сделать такой же вывод, как echo "$@" или echo «${ARRAY[@]}»? printf '%s ' «$@» — не то, заместо переноса строки вконце пробел.

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

а какой между ними разделитель, если, например, echo «$@»?

Разделитель между аргументами вызова программы, пусть и встроенной — это внутренние проблемы интерпретатора и системы. Так для Unix-овго exec — это \0.

ещё не подскажешь, как одной командой printf сделать такой же вывод, как echo «$@» или echo «${ARRAY[@]}»?

Формат вызова у echo и printf — разный. echo простенькая и не очень удобная в большинстве случаев программа, печатающая все аргументы через пробел. Ну так оно по другому, в отличии от printf не умеет, то есть если вам вместо пробела надо что-то другое, то будет облом. Впрочем, если вас устроит лишний пробел в конце, то можно и через printf:

printf "%s " "$@" $'\n'
Но зачем, если для этого простого случая специально придумано «$*»?

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

а если лишний пробел вконце не устроит?

Но зачем, если для этого простого случая специально придумано «$*»?

ну а если массив надо вывести?

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

это я знаю. вопрос был в том, как printf'ом вывести так же как echo "$@" одной командой без лишних пробелов. или ответ "никак"?

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

это я знаю

Не похоже. Я же вам сказал, что для вывода массива в виде строки с одним символом разделителем между элементами в shell-ах специально придуман синтаксис ${arr[*]}.

printf "%s\n" "${ARR[*]}"

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

т.е. только так? через @ так же как echo printf'ом сделать невозможно?

Вы изворачиваетесь тупняком. Если две программы работают по разному синтаксису вызова, но могут быть применены для одной и той же работы, но вторая мощнее первой, то претензии ко второй, что она делает по-другому просто тупняк.

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

я просто надеялся, что есть какой-то хитрый синтаксис форматирующего поля у printf, который действует на неопределённое количество аргументов.

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

я просто надеялся, что есть какой-то хитрый синтаксис форматирующего поля у printf, который действует на неопределённое количество аргументов.

Желание, чтобы разделитель не было для одного элемента, был между двумя элементами и только и один и так далее — это устоявшееся человеческое ощущение «так красивее» и не более того, потому машины человеков и уничтожат, за вот такую нелогичность :))

vodz ★★★★★
()

@vodz, спасибо вам большое за помощь. Но у меня появился новый вопрос, не подскажете?

Как узнать номер терминала и настоящий ли он? Просто надо сделать так, чтобы в ядерной консоли №1 через один и тот же скрипт запускалась программа prog1, в ядерной консоли №2 открывался скриптик script2, а в псевдо-терминалах открывалась программа prog2.

Заранее спасибо.

zagatov_lev
() автор топика
Ответ на: комментарий от zagatov_lev

Как узнать номер терминала и настоящий ли он?

case "$(tty)" in
 /dev/tty[0-9]|/dev/tty[0-9][0-9]) echo -n stdin консоль ;&
 /dev/tty1) echo " 1";;
 /dev/tty1) echo " 2";;
 /dev/tty[0-9]|/dev/tty[0-9][0-9]) echo " другая консоль" ;;
 "not a tty") echo stdin не терминал ;;
 *) echo stdin - терминал, но не ядерная консоль;;
esac
vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.