mScript.sh 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #!/bin/bash
  2. E='echo -e'; # -e включить поддержку вывода Escape последовательностей
  3. e='echo -en'; # -n не выводить перевод строки
  4. c="+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+"
  5. trap "R;exit" 2 #
  6. ESC=$( $e "\e")
  7. TPUT(){ $e "\e[${1};${2}H" ;}
  8. CLEAR(){ $e "\ec";}
  9. # 25 возможно это
  10. CIVIS(){ $e "\e[?25l";}
  11. # это цвет текста списка перед курсором при значении 0 в переменной UNMARK(){ $e "\e[0m";}
  12. MARK(){ $e "\e[1;45m";}
  13. # 0 это цвет списка
  14. UNMARK(){ $e "\e[0m";}
  15. R(){ CLEAR ;stty sane;CLEAR;}; # в этом варианте фон прозрачный
  16. HEAD(){ for (( a=2; a<=41; a++ ))
  17. do
  18. TPUT $a 1
  19. $E "\033[1;35m\xE2\x94\x82 \xE2\x94\x82\033[0m";
  20. done
  21. TPUT 3 3
  22. $E "\033[1;36m*** Script ***\033[0m";
  23. TPUT 4 3
  24. $E "\033[90mCоздать протокол терминальной сессии\033[0m";
  25. TPUT 5 1
  26. $E "\033[35m+---------------------------------------------------------------------------------------------------------------------------------------------+\033[0m";
  27. TPUT 16 1
  28. $E "\033[35m+ Опции --------------------------------------------------------------------------------------- Options --------------------------------------+\033[0m";
  29. TPUT 17 3
  30. $E "\033[90mЗа аргументом размера следуют мультипликативные суффиксы KiB (=1024), MiB (=1024*1024) и т.д. для GiB, TiB, PiB, EiB, ZiB, YiB iB\033[0m";
  31. TPUT 18 3
  32. $E "\033[90mне является обязательным, например, K имеет значение, что KiB), или суффиксы KB (=1000), MB (=1000*1000) и т. д. для GB, TB, PB, EB, ZB, YB\033[0m";
  33. TPUT 36 1
  34. $E "\033[35m+ Команды ------------------------------------------------------------------------------------- Commands -------------------------------------+\033[0m";
  35. TPUT 39 1
  36. $E "\033[35m+ Up \xE2\x86\x91 \xE2\x86\x93 Down Select Enter -------------------------------------------------------------------------------------------------------------------+\033[0m";
  37. MARK;TPUT 1 1
  38. $E "$c";UNMARK;}
  39. i=0; CLEAR; CIVIS;NULL=/dev/null
  40. # 32 это расстояние сверху и 48 это расстояние слева
  41. FOOT(){ MARK;TPUT 42 1
  42. $E "$c";UNMARK;}
  43. # это управляет кнопками ввер/хвниз
  44. i=0; CLEAR; CIVIS;NULL=/dev/null
  45. #
  46. ARROW(){ IFS= read -s -n1 key 2>/dev/null >&2
  47. if [[ $key = $ESC ]];then
  48. read -s -n1 key 2>/dev/null >&2;
  49. if [[ $key = \[ ]]; then
  50. read -s -n1 key 2>/dev/null >&2;
  51. if [[ $key = A ]]; then echo up;fi
  52. if [[ $key = B ]];then echo dn;fi
  53. fi
  54. fi
  55. if [[ "$key" == "$($e \\x0A)" ]];then echo enter;fi;}
  56. M0(){ TPUT 6 3; $e " Установка \033[90minstall \033[0m";}
  57. M1(){ TPUT 7 3; $e " Oбзор \033[90mSynopsis \033[0m";}
  58. M2(){ TPUT 8 3; $e " Описание \033[90mDescription \033[0m";}
  59. M3(){ TPUT 9 3; $e " Сигналы \033[90mSignals \033[0m";}
  60. M4(){ TPUT 10 3; $e " Окружающая среда \033[90mEnvironment \033[0m";}
  61. M5(){ TPUT 11 3; $e " Примечания \033[90mNotes \033[0m";}
  62. M6(){ TPUT 12 3; $e " История \033[90mHistory \033[0m";}
  63. M7(){ TPUT 13 3; $e " Ошибки \033[90mBugs \033[0m";}
  64. M8(){ TPUT 14 3; $e " Смотрите также \033[90mSee Also \033[0m";}
  65. M9(){ TPUT 15 3; $e " Доступность \033[90mAvailability \033[0m";}
  66. #
  67. M10(){ TPUT 19 3; $e " Добавьте вывод в файл или в машинописный текст \033[32m-a --append \033[0m";}
  68. M11(){ TPUT 20 3; $e " Запустите команду, а не интерактивную оболочку \033[32m-c --command command \033[0m";}
  69. M12(){ TPUT 21 3; $e " Управление флагом echo для псевдотерминала в сеансе \033[32m-E --echo when \033[0m";}
  70. M13(){ TPUT 22 3; $e " Возвращает статус выхода дочернего процесса \033[32m-e --return \033[0m";}
  71. M14(){ TPUT 23 3; $e " Сбрасывать вывод после каждой записи \033[32m-f --flush \033[0m";}
  72. M15(){ TPUT 24 3; $e " Разрешить машинописи выходного файла быть жесткой или символической ссылкой \033[32m --force \033[0m";}
  73. M16(){ TPUT 25 3; $e " Записывайте ввод и вывод в один и тот же файл \033[32m-B --log-io file \033[0m";}
  74. M17(){ TPUT 26 3; $e " Вывод журнала отключен, если указан только параметр --log-in \033[32m-I --log-in file \033[0m";}
  75. M18(){ TPUT 27 3; $e " Данные записываются в файл с именем typescript, если опция --log-out или --log-in не указана \033[32m-O --log-out file \033[0m";}
  76. M19(){ TPUT 28 3; $e " Запишите информацию о времени в файл \033[32m-T --log-timing file \033[0m";}
  77. M20(){ TPUT 29 3; $e " Принудительное использование расширенного или классического формата \033[32m-m --logging-format format \033[0m";}
  78. M21(){ TPUT 30 3; $e " Классический формат \033[90mClassic format \033[0m";}
  79. M22(){ TPUT 31 3; $e " Ограничьте размер машинописного текста и файлов синхронизации \033[32m-o --output-limit size \033[0m";}
  80. M23(){ TPUT 32 3; $e " Hе выводите сообщения start и done в стандартный вывод \033[32m-q --quiet \033[0m";}
  81. M24(){ TPUT 33 3; $e " Вывод данных синхронизации в стандартную ошибку или в файл \033[32m-t[file] --timing[=file] \033[0m";}
  82. M25(){ TPUT 34 3; $e " Показать информацию о версии и выйти \033[32m-V --version \033[0m";}
  83. M26(){ TPUT 35 3; $e " Показать текст справки и выйти \033[32m-h --help \033[0m";}
  84. #
  85. M27(){ TPUT 37 3; $e " Запись \033[32mscript \033[0m";}
  86. M28(){ TPUT 38 3; $e " Воспроизведение \033[32mscriptreplay \033[0m";}
  87. #
  88. M29(){ TPUT 40 3; $e "\033[90mExit \033[0m";}
  89. LM=29
  90. MENU(){ for each in $(seq 0 $LM);do M${each};done;}
  91. POS(){ if [[ $cur == up ]];then ((i--));fi
  92. if [[ $cur == dn ]];then ((i++));fi
  93. if [[ $i -lt 0 ]];then i=$LM;fi
  94. if [[ $i -gt $LM ]];then i=0;fi;}
  95. REFRESH(){ after=$((i+1)); before=$((i-1))
  96. if [[ $before -lt 0 ]];then before=$LM;fi
  97. if [[ $after -gt $LM ]];then after=0;fi
  98. if [[ $j -lt $i ]];then UNMARK;M$before;else UNMARK;M$after;fi
  99. if [[ $after -eq 0 ]] || [ $before -eq $LM ];then
  100. UNMARK; M$before; M$after;fi;j=$i;UNMARK;M$before;M$after;}
  101. INIT(){ R;HEAD;FOOT;MENU;}
  102. SC(){ REFRESH;MARK;$S;$b;cur=`ARROW`;}
  103. # Функция возвращения в меню
  104. ES(){ MARK;$e " ENTER = main menu ";$b;read;INIT;};INIT
  105. while [[ "$O" != " " ]]; do case $i in
  106. 0) S=M0;SC;if [[ $cur == enter ]];then R;echo " sudo apt install script";ES;fi;;
  107. 1) S=M1;SC;if [[ $cur == enter ]];then R;echo " script [options] [file]";ES;fi;;
  108. 2) S=M2;SC;if [[ $cur == enter ]];then R;echo " script создает машинописный текст всего, что происходит в вашей терминальной сессии. Данные терминала сохраняются в необработанном виде в файл журнала и
  109. информация о времени до другой (необязательный) структурированный файл журнала. Файл журнала синхронизации необходим для последующего воспроизведения сеанса с
  110. помощью scriptreplay и для хранения дополнительной информации. речь о сеансе.
  111. Начиная с версии 2.35, скрипт поддерживает несколько потоков и позволяет протоколировать ввод и вывод в отдельные файлы или все в один файл. Эта версия также
  112. поддерживает новый файл синхронизации, в который записывается дополнительная информация. Затем команда scriptreplay --summary предоставляет всю информацию.
  113. Если задан файл аргумента или опция --log-out file, скрипт сохраняет диалог в этом файле. Если имя файла не указано, диалог сохраняется в файле машинопись.
  114. Обратите внимание, что входные данные журнала с использованием --log-in или --log-io могут записывать конфиденциальную информацию, поскольку файл журнала содержит
  115. все входные данные сеанса терминала (например, пароли) независимо от установки эхо-флажка терминала.";ES;fi;;
  116. 3) S=M3;SC;if [[ $cur == enter ]];then R;echo " Получив SIGUSR1, скрипт немедленно сбрасывает выходные файлы.";ES;fi;;
  117. 4) S=M4;SC;if [[ $cur == enter ]];then R;echo " Следующая переменная среды используется сценарием:
  118. SHELL Если переменная SHELL существует, оболочка, разветвленная скриптом, будет этой оболочкой.
  119. Если SHELL не установлен, предполагается оболочка Bourne. (Большинство оболочек устанавливают эту переменную автоматически).";ES;fi;;
  120. 5) S=M5;SC;if [[ $cur == enter ]];then R;echo "
  121. Сценарий завершается при выходе из разветвленной оболочки (control-D для оболочки Bourne (sh(1p)) и выхода из системы или control-d (если ignoreeof не
  122. установлен) для C- оболочка, csh).
  123. Некоторые интерактивные команды, такие как vi, создают мусор в машинописном файле. сценарий лучше всего работает с командами, которые не управляют экраном,
  124. результаты предназначены для эмуляции печатного терминала.
  125. Не рекомендуется запускать скрипт в неинтерактивных оболочках. Внутренняя оболочка скрипта всегда интерактивна, и это может привести к неожиданным результатам.
  126. Если вы используете сценарий в файле инициализации оболочки, вы должны избегать входа в бесконечный цикл. Вы можете использовать, например, файл .profile, который
  127. читается только с помощью оболочек входа:
  128. if test -t 0 ; then
  129. script
  130. exit
  131. fi
  132. Вам также следует избегать использования сценария в командных каналах, так как сценарий может считывать больше входных данных, чем вы ожидаете.
  133. ";ES;fi;;
  134. 6) S=M6;SC;if [[ $cur == enter ]];then R;echo " Команда script появилась в 3.0BSD.";ES;fi;;
  135. 7) S=M7;SC;if [[ $cur == enter ]];then R;echo " script помещает все в файл журнала, включая переводы строки и символы возврата. Это не то, что ожидает наивный пользователь. script в первую очередь
  136. предназначен для интерактивных сеансов терминала. Когда стандартный ввод не является терминалом (например: echo foo | script), сеанс может зависнуть, потому что
  137. интерактивная оболочка в сеансе сценария пропускает EOF, а сценарий не знает, когда закрыть сеанс. Дополнительную информацию см. в разделе ПРИМЕЧАНИЯ.";ES;fi;;
  138. 8) S=M8;SC;if [[ $cur == enter ]];then R;echo " csh (для механизма истории), scriptreplay, scriptlive";ES;fi;;
  139. 9) S=M9;SC;if [[ $cur == enter ]];then R;echo " Команда script является частью пакета util-linux и доступна в архиве ядра Linux: https://www.kernel.org/pub/linux/utils/util-linux/";ES;fi;;
  140. 10) S=M10;SC;if [[ $cur == enter ]];then R;echo " Добавьте вывод в файл или в машинописный текст, сохранив предыдущее содержимое.";ES;fi;;
  141. 11) S=M11;SC;if [[ $cur == enter ]];then R;echo " Запустите команду, а не интерактивную оболочку. Это упрощает для сценария захват вывода программы, которая ведет себя по-разному, когда его стандартный вывод
  142. не является tty.";ES;fi;;
  143. 12) S=M12;SC;if [[ $cur == enter ]];then R;echo " Эта опция управляет флагом ECHO для псевдотерминала в сеансе. Поддерживаемые режимы: всегда, никогда или автоматически. По умолчанию авто -- в этом случае echo
  144. отключается, если текущий стандартный ввод является терминалом, чтобы избежать двойного эха, и включается, если стандартный ввод не является терминалом (например,
  145. pipe: echo date | script), чтобы не пропустить ввод в журнале сеанса.";ES;fi;;
  146. 13) S=M13;SC;if [[ $cur == enter ]];then R;echo " Возвращает статус выхода дочернего процесса. Использует тот же формат, что и bash-завершение при завершении сигнала (т. е. статус выхода — 128 + сигнал номер).
  147. Статус выхода дочернего процесса также всегда хранится в файле сценария типа.";ES;fi;;
  148. 14) S=M14;SC;if [[ $cur == enter ]];then R;echo " Сбрасывать вывод после каждой записи. Это хорошо для телесотрудничества: один человек делает mkfifo foo; script -f foo, а другой может контролировать в
  149. реале время, что делается с помощью cat foo Обратите внимание, что сброс влияет на производительность; можно использовать SIGUSR1 для очистки журналов по запросу.";ES;fi;;
  150. 15) S=M15;SC;if [[ $cur == enter ]];then R;echo " Разрешить машинописи выходного файла по умолчанию быть жесткой или символической ссылкой. Команда будет следовать символической ссылке.";ES;fi;;
  151. 16) S=M16;SC;if [[ $cur == enter ]];then R;echo " Записывайте ввод и вывод в один и тот же файл. Обратите внимание, эта опция имеет смысл только в том случае, если также указан --log-timing, иначе невозможно
  152. разделить выходные и входные потоки из файла журнала.";ES;fi;;
  153. 17) S=M17;SC;if [[ $cur == enter ]];then R;echo " Журнал ввода в файл. Вывод журнала отключен, если указан только параметр --log-in. Используйте эту функцию ведения журнала с осторожностью, так как она
  154. регистрирует все вводимые данные, включая ввод, когда терминал отключил echo флаг (например, ввод пароля).";ES;fi;;
  155. 18) S=M18;SC;if [[ $cur == enter ]];then R;echo " Вывод журнала в файл. По умолчанию выходные данные записываются в файл с именем typescript, если опция --log-out или --log-in не указана.
  156. Журнал вывод отключен, если указан только --log-in.";ES;fi;;
  157. 19) S=M19;SC;if [[ $cur == enter ]];then R;echo " Запишите информацию о времени в файл. Теперь поддерживаются два формата файлов синхронизации. Классический формат используется, когда только один поток (входной
  158. или выходной) ведение журнала включено. Многопоточный формат используется в --log-io или когда --log-in и --log-out используются вместе. См. также --log-format.";ES;fi;;
  159. 20) S=M20;SC;if [[ $cur == enter ]];then R;echo " Принудительное использование расширенного или классического формата. По умолчанию используется классический формат для регистрации только вывода и расширенный
  160. формат для ввода и вывода запрошена регистрация.";ES;fi;;
  161. 21) S=M21;SC;if [[ $cur == enter ]];then R;echo " Журнал содержит два поля, разделенных пробелом. Первое поле указывает, сколько времени прошло с момента предыдущего вывода. Второе поле указывает, сколько
  162. символов было выведено на этот раз.
  163. Расширенный (многопоточный) формат. Первое поле представляет собой идентификатор типа записи ('I'nput, 'O'utput, 'H'eader, 'S'ignal). Второе поле показывает,
  164. сколько времени прошло с момента предыдущего запись, а остальная часть записи является данными, специфичными для типа.";ES;fi;;
  165. 22) S=M22;SC;if [[ $cur == enter ]];then R;echo " Ограничьте размер машинописного текста и файлов синхронизации до размера и остановите дочерний процесс после превышения этого размера. Расчетный размер файла не
  166. включать сообщения о запуске и завершении, которые команда сценария добавляет в начале и в конце к выходным данным дочернего процесса. Из-за буферизации
  167. результирующий put-файл может быть больше указанного значения.";ES;fi;;
  168. 23) S=M23;SC;if [[ $cur == enter ]];then R;echo " Будьте спокойны (не выводите сообщения start и done в стандартный вывод).";ES;fi;;
  169. 24) S=M24;SC;if [[ $cur == enter ]];then R;echo " Вывод данных синхронизации в стандартную ошибку или в файл, если они заданы.
  170. Этот параметр устарел в пользу --log-timing, где аргумент файла не является необязательным.";ES;fi;;
  171. 25) S=M25;SC;if [[ $cur == enter ]];then R;echo " ";ES;fi;;
  172. 26) S=M26;SC;if [[ $cur == enter ]];then R;echo " ";ES;fi;;
  173. 27) S=M27;SC;if [[ $cur == enter ]];then R;echo "
  174. В файл timing.txt записываeтся тайминг, что позволит сохранить интервалы между выводами текста на экран, а в файл record.txt — сами команды и результат работы:
  175. script -t -a 2>timing.txt record.txt
  176. ";ES;fi;;
  177. 28) S=M28;SC;if [[ $cur == enter ]];then R;echo "
  178. Воспроизведение Для просмотра записи используйте команду:
  179. scriptreplay timing.txt record.txt
  180. Можно также просто вывести содержимое файла record.txt на экран, либо открыть его в вашем любимом редакторе.
  181. ";ES;fi;;
  182. #
  183. 29) S=M29;SC;if [[ $cur == enter ]];then R;exit 0;fi;;
  184. esac;POS;done