Отсроченное расширение

Я хочу создать скрипт quine .sh, и это то, что я сделал до сих пор:
quine.sh :

 #!/bin/sh q="#!/bin/sh\nq=$q;echo \$q";echo $q 

Сосредоточьтесь на этой строке:

 q="#!/bin/sh\nq=$q;echo \$q";echo $q 

При первом вводе $q\nq=$q ) я сначала хочу установить остальную часть переменной, а затем эту часть (что-то строка setlocal enabledelayedexpansion в пакетных файлах). Обратите внимание, что я хочу решение для sh , а не bash или что-то еще, поскольку я хочу переносимость . Кроме того, не давайте мне советы о том, как сделать код короче и т. Д. Я просто хочу решить проблему выше.

One Solution collect form web for “Отсроченное расширение”

Если мы обернем исходную строку в ' s вместо s, тогда $q не будет немедленно расширена. Затем мы можем ее расширить позже, используя eval :

 #!/bin/sh q='#!/bin/sh\nq=$q;eval "echo \"\$q\""';eval "echo \"$q\"" 

К сожалению, \n не расширяется, s и s теряются, и они становятся.

Вывод:

 #!/bin/sh\nq=#!/bin/sh\nq=$q;eval "echo \"\$q\"";eval echo "$q" 

Мы довольно близки, но попытка исправить побег с помощью sed заканчивается, становясь довольно громоздкой.


Ссылка jw013 рекомендует довольно понятный подход:

  • Часть 1: Определите некоторые данные (например, переменную), которая содержит вторую часть программы
  • Часть 2: Используйте данные для вывода первой части программы, а затем используйте данные для вывода второй части программы. (Ручная упаковка и экранирование необходимы для части 1 здесь.)

Вот начальная грубая попытка:

 #!/bin/sh data="echo -e \"#!/bin/sh\ndata=\"\$data\"\"\\n\$data" echo -e "#!/bin/sh\ndata=\"$data\"\n$data" 

Вывод:

 #!/bin/sh data="echo -e "#!/bin/sh data="$data"" $data" echo -e "#!/bin/sh data="$data"" $data 

Эта попытка страдает от того, что \n всегда интерпретируется и \ s теряется. Нам нужно каким-то образом избежать строки данных, когда мы снова напечатаем ее.


Вот улучшение, которое использует несколько вызовов для echo , чтобы избежать проблем с \n s.

 #!/bin/sh data='echo "#!/bin/sh"\necho "data=$data"\necho -e "$data"' echo "#!/bin/sh" echo "data='$data'" echo -e "$data" 

Он страдает одним крошечным недостатком, который трудно преодолеть, отсутствием на выходе (среднее echo ):

 #!/bin/sh data='echo "#!/bin/sh"\necho "data=$data"\necho -e "$data"' echo "#!/bin/sh" echo "data=$data" echo -e "$data" 

Это все, что у меня есть для тебя. Некоторые отправные точки с устранением проблем. Удачи!

  • Переход на суперпользователь при запуске скрипта оболочки
  • Неожиданное поведение сценария оболочки
  • Объединение нескольких файлов в один CSV
  • Преобразование `для файла в` для `find`, чтобы мой скрипт мог применяться рекурсивно
  • Как выполнить сценарий оболочки при запуске Kali Linux?
  • как удалить последнюю черту пути каталога?
  • Запустить команду на одноименные файлы из нескольких каталогов
  • Cronjob перезаписывает перенаправление сценария
  • Сценарий Bash для удаления каталогов старше 5 дней?
  • Как выбрать самый старый файл в папке из каталога
  • Как подождать подпроцесс, используемый для перенаправления ввода-вывода?
  • Linux и Unix - лучшая ОС в мире.