Нет, здесь строки недоступны для ksh88
и pdksh
. Однако в более позднихksh93
(оригинальных AT&T Korn Shell )иmksh
(в настоящее время активно разрабатываемых pdksh
производных )он доступен.
<<<
является одним из «современных» расширений оболочки, используемых ksh93
, mksh
, GNU bash
и zsh
.
Ваша конкретная проблема…
read A B C <<< $line
… можно обойти с помощью (оболочки Korn):
print -r -- $line |&
read -p A B C
Вы также можете использовать эту (оболочку POSIX ), она снижает производительность tmpfile, хотя (с другой стороны, <<<
, вероятно, также имеет):
read A B C <<EOF
$line
EOF
Если вы просто хотите разделить слова:
set -A arrname -- $line
Затем используйте ${arrname[0]}
вместо $A
и ${arrname[1]}
вместо $B
. Только он не остановится на разбиении на три элемента, так что если $line
равно "foo bar baz bla
", то $C
будет содержать "баз бла", тогда как ${arrname[2]}
содержит "баз", а ${arrname[3]}
содержит "бла".
Если вам не нужны позиционные параметры, вы можете
set -- $line
A=$1; shift
B=$1; shift
C=$*
shift
вызовет ошибки, если $line
содержит менее трех слов, хотя (проверьте $#
, если вы не уверены, или используйте [[ $line = *' '*' '[! ] ]]
(, вероятно, медленнее, хотя ), чтобы сначала проверить ).
Имейте в виду, что set … $line
также будет выполнять подстановку (спасибо Стефану за напоминание ), поэтому вам нужно set -o noglob
перед (и, возможно, после этого восстановить предыдущее состояние, обычноset +o noglob
).
Полное раскрытие :Я mksh
разработчик.
Нет, здесь -строки взяты из zsh
в версии 2.0 в 1991 году (и/или из Unix-порта rc
, их соответствующие авторы примерно в то время обменивались идеями, неясно, кто из них имел идею или включил ее в свою оболочку первым ).
Был добавлен в bash в 2.05b (2002 ), ksh93 в m+ (2002 ), mksh в R33 (2008 ),яш в 2.7 (2009 ).
ksh88 не получает никаких новых функций.
Вот документы (<<
), сами исходят из оболочки Борна -конца 70-х.
read A B C
считывает одну логическую строку в переменные A
, B
и C
очень особым образом (немного менее специальным образом со значением по умолчанию $IFS
, которое содержит только IFS -белые -символы пробела¹ ), с обратной косой чертой, действующей как экранирующий и символ продолжения строки -, и то, что входит в C
, также довольно сложно. Проделать то же самое без read
было бы довольно сложно.
Во всяком случае, здесь <<<
— это то же самое, что и <<
, только синтаксические отличия.
read A B C << EOF
$var
EOF
точно такое же, как
read A B C <<< "$var" # note that some versions of bash need the quotes
во всех оболочках. В обоих случаях оболочка создает удаленный временный файл с содержимым и дополнительной новой строкой (, хотя некоторые оболочки вместо этого используют каналы ). Затем read
считывает из нее одну логическую строку (, возможно, несколько физических строк, продолженных обратной косой чертой ), и заполняет переменные, используя свои сложные правила.
Он назначает только первые 3 слова (SPC/TAB с разделителями )из $var
на $A
, $B
и $C
, если
$IFS
по-прежнему содержит значение по умолчанию Для первых трех слов вы можете:
function split_into {
typeset words IFS v i=0
set -o noglob
set -A words -- $1; shift
for v do
eval "$v=\${words[i]}"
((i += 1))
done
}
split_into "$var" A B C
¹ Пробельные символы IFS , согласно POSIX, это символы, классифицируемые как [:space:]
в локали и находящиеся в $IFS
, хотя в ksh88 (, на котором основана спецификация POSIX )и в большинстве оболочек это по-прежнему ограничено SPC, TAB и NL. Единственной совместимой с POSIX оболочкой, которую я нашел в этом отношении, была yash
. ksh93
иbash
(начиная с версии 5.0 )также включают другие пробелы (, такие как CR,FF, VT... ), но ограничены одиночными -байтами (, будьте осторожны в некоторых системах, таких как Solaris, которые включают неразрывное -пространство -, которое в некоторых локалях является одним байтом)