Команда Bash у рядку виконується, коли я створюю рядок, а не коли я її використовую пізніше


10

Я відносно новачок сценаріїв оболонок, але майже завершив сценарій, який використовує програму lftp . Частина сценарію, з якою я маю проблеми, - це коли я створюю довгий рядок команд (розділений на ;).

for var in something
do
    ...
    commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done

Що я помічаю, це те, що tailпрограма, загорнута в беккетки, запускається тоді, коли цикл for ітерирується, але не тоді, коли я пізню рядок команд пізніше у своєму сценарії.

На жаль, вміст $ somefile ще не готовий до перевірки. Як я можу отримати команду для виконання, коли мені це потрібно, а не під час створення рядка?

Відповіді:


8

Це трохи хитро. Інформація, яку надав Хоуке, є правильною, це лише питання розбору її для вашого випадку використання.

Найпростіший спосіб - використовувати $()синтаксис, уникаючи $такого, щоб визначення змінної не виконувало команди, додані $()до моменту визначення. Застереження полягає в тому, що кінцевий результат повинен бути повторно оцінений (через eval) оболонкою під час фактичного виконання вкладеної команди для виконання.

Набагато простіше подивитися на приклад, тому візьміть цей, який повинен поставити вас на правильний шлях:

for((i=0;i<10;i++)); do 
  date +%s.%N  # Print a timestamp (in format seconds.nanoseconds)
  test="echo \$(date +%s.%N)" # Save a command to do the same
  sleep 1      # Sleep for a second
  eval "$test" # Evaluate the command saved in variable 'test'
  echo         # Print a new line before the next iteration
done

Ось зразок виводу з наведеного вище прикладу (оброблений однією ітерацією):

1398832186.133661344
1398832187.139076728

Ви помітите, що друга мітка часу для кожного циклу - приблизно секунда після першої. І навпаки, якщо ви виконаєте один і той же тест, не ухиляючись $від testвизначення та не видаляючи eval, дві часові позначки майже збігаються.

Не вживайте звички використовувати evalв більшості ситуацій, але це одна з тих, де я не знаю хорошого способу уникнути цього. Сподіваємось, це допомагає. Удачі!


Дякую велике, я намагався використовувати так, $(...)як запропонував Хоуке, але ключовим є зворотний нахил.
Рікі

Рада, що це допомогло - пам’ятайте, що, правда, ключ тут справді полягає в evalтому, що ви можете зробити те ж саме, не уникаючи $та використовуючи одинарні лапки ( '), а не подвійні лапки ( ") для оточення своєї команди.
daBeamer

Тепер я лише зрозумів, як і в пропозиціях Хуаке, як тільки я спробую використовувати це в програмі lftp, ехо просто друкує команду, вона насправді не запустить її. Можливо, доведеться спробувати їх розсилку для отримання конкретнішої допомоги.
Рікі

Яку команду ви намагаєтеся виконати? У мене було враження, що ви хочете echoотримати рядок із вмістом, включаючи вихід вкладеної команди із запізненням на виконання.
daBeamer

1
@Ricky Я би погодився з усіма пунктами @HaukeLaging. Код як-мінус echoне працює, тому що немає команди eval, а лише рядка. Якщо у вас є більш доречний приклад для нас, ми можемо спробувати допомогти.
daBeamer

6

Існує кілька рівнів цитування. Подвійні лапки ( "...") ЗАХИСТИТИ прогалини і кілька спеціальних символів ( ~, &, |, ;, ...) , але не запобігає підстановка параметрів і команд.

Вам потрібні або окремі лапки ( '), або зворотна косої риси перед "небезпечними" символами.

Взагалі: Вам слід розглянути можливість використання $(tail ...)замість задніх планок. Бекстік - це старший стандарт, але ми говоримо про такий старий, що $()не створює проблем для більшості людей. Нова версія легше читати і може вкладатись. Не кажучи вже про проблеми з форматуванням тут на sx ...


Дякую за швидку відповідь Хоуке. На жаль, підстановка зворотних посилань на рекомендовані $(...)все одно дає такий же результат - оболонка виконує це, коли буде визначено мій рядок.
Рікі

@Ricky Це були не альтернативні пропозиції. Ви будете використовувати, $()але вам потрібні одиничні цитати в будь-якому випадку.
Hauke ​​Laging

Тож жодне поєднання цих персонажів не досягне того, що я шукаю?
Рікі

@ Ricky Що так важко зрозуміти у "Вам потрібні або окремі цитати"? Ви, очевидно, навіть не спробуйте.
Hauke ​​Laging

Насправді я так і зробив, але коли я використовую одинарні лапки, ехо просто надрукує все на цьому рядку як звичайний рядок. Що так важко, можливо, навести приклад?
Рікі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.