2014-11-10 7 views
5

У меня есть переменная, которая выглядит вроде этого:Что такое POSIX оболочки эквивалент Баш <<<

msg="newton apple tree" 

Я хочу, чтобы присвоить каждому из этих слов в отдельные переменные. Это легко сделать в bash:

read a b c <<< $msg 

Есть ли компактный, читаемый способ сделать это в оболочке POSIX?

+0

«bash» означает «Bourne Again Shell». Это большая, лучшая, более быстрая версия «Bourne Shell». Так что это маловероятно. – Sobrique

+0

Я не знаю, как * читаемый * вы бы это рассмотрели, но это сводится к использованию трубы. Возможно ли, что вы уже отказались? – hardmath

+2

Если существовал POSIX sh (вы, вероятно, на самом деле не имеете в виду Bourne - Bourne - это оболочка из 70-х годов, если вы не находитесь на умеренно-старой Solaris, у кого нет Bourne), то почему bash пришлось представить особенность? –

ответ

8

Чтобы написать идиоматические скрипты, вы не можете просто смотреть на каждый отдельный элемент синтаксиса и попробовать найти эквивалент POSIX. Это похоже на перевод текста путем замены каждого отдельного слова его записью в словаре.

POSIX способ разделения строки, как известно, есть три слова в три аргумента, похожих, но не идентичных read является:

var="newton apple tree" 

set -f 
set -- $var 
set +f 
a=$1 b=$2 c=$3 

echo "$a was hit by an $b under a $c" 
+0

Я мог бы сделать эту работу в функции, чтобы избежать перезаписи глобальной '$ @', но это отличное решение. –

+2

Это излишне перезаписывает позиционные параметры; строка здесь является просто ярлыком для однострочных документов, поэтому нет необходимости заменять 'read' командой' set'. – chepner

3

Это не очень, но как универсальное решение, вы можете обойти это с помощью именованного канала.

От BashFAQ #24:

mkfifo mypipe 
printf '%s\n' "$msg" >mypipe & 
read -r a b c <mypipe 

printf является более надежным/лучше, чем указано echo; поведение эха варьируется между реализациями, если у вас есть сообщение, содержащее только, скажем, -E или -n.


Это говорит, за то, что вы здесь делаете, вы могли бы просто использовать расширение параметра:

a=${msg%% *}; msg=${msg#* } 
b=${msg%% *}; msg=${msg#* } 
c=${msg%% *}; msg=${msg#* } 
+0

Я думаю, вам нужно добавить 'a b c' вместо строки, чтобы сделать ее более подходящей для моего примера. Но это похоже на возможный ответ. – Bitdiot

+0

ах, хорошо, что выглядит лучше. – Bitdiot

+0

Я бы хотел дать вам чек, но я думаю, что у этого парня более элегантное решение. Надеюсь, ты не против. – Bitdiot

10

А вот строка просто синтаксический сахар для одной линии здесь документа:

$ msg="foo * bar" 
$ read a b c <<EOF 
> $msg 
> EOF 
$ echo "$a" 
foo 
$ echo "$b" 
* 
$ echo "$c" 
bar 
Смежные вопросы