как я могу назначить вывод команды для переменной shell?

<p>я хочу присвоить результат выражения переменной и объединить его со строкой, а затем повторить его. вот что у меня есть:</p><pre><code>#!/bin/bash cd ~/desktop; thefile= ls -t -u | grep -m 1 "screen shot"; echo "most recent screenshot is: "$thefile; но это выводит:screen shot 2011-07-03 at 1.55.43 pm.png most recent screenshot is: итак, похоже, что это не назначается $thefile</code> и печатается по мере выполнения.</p>

<p>назначение оболочки - это одно слово без пробела после знака равенства. итак, то, что вы написали, присваивает пустое значение <code>thefile</code>; кроме того, поскольку назначение сгруппировано с помощью команды, это делает <code>thefile</code> переменной среды, и назначение является локальным для этой конкретной команды, т. е. только вызов <code>ls</code> видит назначенное значение.</p><p>вы хотите захватить вывод команды, поэтому вам нужно использовать <a href="http://tldp.org/ldp/abs/html/commandsub.html">подстановка команды</a> :</p><pre>\_<code>thefile=$(ls -t -u | grep -m 1 "screen shot") _(некоторые литературные источники показывают альтернативный синтаксис _thefile=ls …_; синтаксис обратных кавычек эквивалентен синтаксису долларовых скобок, за исключением того, что кавычки внутри обратных кавычек иногда бывают странными, поэтому просто используйте $(…)</code>.)</p><p>другие замечания о вашем сценарии:</p><ul> <li>объединение \_<code>-t</code>\_ (сортировка по времени) с \_<code>-u</code>\_ (не сортировка) не имеет смысла; просто используйте \_<code>-t</code>\_.</li> <li> <p>вместо того, чтобы использовать <code>grep</code> для сопоставления снимков экрана, проще передать подстановочный знак <code>ls</code> и использовать <code>head</code> для захвата первого файла:</p> <pre>\_<code>thefile=$(ls -t "screen shot" | head -n 1) _  обычно это <a href="http://mywiki.wooledge.org/parsingls">плохая идея разбирать вывод ls . это может плохо работать, если у вас есть имена файлов с непечатными символами. однако сортировать файлы по дате сложно без ls, поэтому это приемлемое решение, если вы знаете, что у вас не будет непечатных символов или обратной косой черты в именах файлов.   <strong> всегда используйте двойные кавычки вокруг подстановки переменных </strong>, т.е. здесь пишите _echo "most recent screenshot is: $thefile" </code>\_</pre> <p>без двойных кавычек значение переменной будет расширено, что вызовет проблемы, если оно содержит пробелы или другие специальные символы.</p> </li> <li>вам не нужны точки с запятой в конце строки. они избыточны, но безвредны.</li> <li>в сценарии оболочки часто рекомендуется включать <a href="http://www.davidpashley.com/articles/writing-robust-shell-scripts.html">\_<code>set -e</code>\_</a> . это говорит командной консоли завершить работу в случае сбоя какой-либо команды (возвращая ненулевой статус).</li> </ul><p>если у вас есть gnu find (в частности, если вы работаете с не встроенным linux или cygwin), есть другой подход к поиску самого последнего файла: попросите <code>find</code> перечислить файлы и их даты, и используйте <code>sort</code> и <code>tail</code>, чтобы извлечь самый младший файл.</p><pre>\_<code>thefile=$(find -maxdepth 1 -type f -name "screen shot" -printf "%t@ %p" | sort -k 1n | tail -n 1) _если вы хотите написать этот скрипт на zsh вместо bash, есть гораздо более простой способ перехватить новейший файл, потому что zsh имеет <a href="http://zsh.sourceforge.net/doc/release/expansion.html#glob-qualifiers">glob qualifiers , который разрешает подстановочные совпадения не только для имен, но и для файла. метаданные. часть _(om[1])_ после шаблона - это квалификаторы glob; om сортирует совпадения по возрасту (т. е. по времени модификации, сначала самое новое), а _[1]_ извлекает только первое совпадение. все совпадения должны быть в скобках, потому что технически это массив, так как глобализация возвращает список файлов, даже если _[1]_ означает, что в данном конкретном случае список содержит (максимум) один файл._#!/bin/zsh set -e cd ~/desktop thefile=("screen shot"(om[1])) echo "most recent screenshot is: $thefile" </code>\_</pre>

<p>если вы хотите сделать это с помощью нескольких строк/нескольких команд/с, то вы можете сделать это:</p><pre><code>output=$( bash <<eof #multiline/multiple command/s eof ) или:output=$( #multiline/multiple command/s ) </code></pre><p>пример:</p><pre><code>#!/bin/bash output="$( bash <<eof echo first echo second echo third eof )" echo "$output" </code></pre><p>вывод:</p><pre><code>first second third </code></pre>