Можно ли просмотреть историю другой оболочки?

Стандартным разделителем, используемым в командах sed, является /, как в командах вроде этой:

sed -e s/foo/bar/g < input > output

Однако, если за командой s следует другой символ, этот становится разделителем для этого конкретного выражения.

Использование не/ разделителей часто встречается, когда разделитель сам должен появиться в команде и поэтому требует тщательного внимания к экранированию. Например, разделитель / раздражает в сценариях, работающих с путями Unix.

Здесь этого нет, поэтому я предполагаю, что автор этой команды просто предпочитает : в качестве разделителя в командах sed.

Ваша команда содержит пять выражений:

s:::

Это заменяет первый экземпляр в каждой строке ввода на в выводе. Если во входных данных в данной строке имеется более одного совпадения, последующие будут оставлены без внимания.

Одинарные кавычки просто не позволяют оболочке интерпретировать любой из символов в выражении. Все они передаются буквально команде sed.

s:::

Аналогично вышеприведенному случаю, только, очевидно, для другого пола.

s:([0-9])::g

Удаляет из строк ввода все одиночные цифры в круглых скобках.

В отличие от предыдущих двух выражений, это выражение затрагивает все экземпляры в каждой строке, поскольку в конце стоит g, что означает "глобальный".

Обратите внимание, что оно работает только с одиночными цифрами. Это ничего не сделает, например, с (42).

s:::g

Удаляет все экземпляры из каждой строки ввода при записи на вывод.

s:([^ ]*)$:::

Удаляет символ круглой скобки в конце строки, если он не содержит пробела. Также удаляет пустую пару круглых скобок в конце строки.

Есть целые книги по этим темам, sed и регулярным выражениям. Один ответ действительно не подходит для изучения всей темы.

Приведенное выше выражение на самом деле немного хитрое в этом отношении: $ прикрепляет регулярное выражение (или regex для краткости) к концу строки, а ^ - к началу, но ^ в этом выражении означает что-то другое.

Я рекомендую вам прочитать Mastering Regular Expressions Джеффри Фридла.

5
31.01.2017, 20:06
3 ответа

Нет, bash не поддерживает это. История хранится в памяти и недоступна для других процессов, пока она не будет сохранена в .bash_history в том же сеансе с использованием history -a или history -w . Но в момент записи в файловую систему информация о том, из какого сеанса была создана команда, теряется.

Самое близкое, что вы можете получить, - это использовать несколько строк в .bashrc , чтобы bash добавлял каждую команду сразу после выполнения: https://unix.stackexchange.com/ a / 1292/147970
Затем вы можете видеть команды из всех оболочек почти в реальном времени в .bash_history .

Чтобы получить доступ к истории для определенного сеанса, вам необходимо прервать процесс переднего плана в этом сеансе, например, Ctrl + Z .

4
27.01.2020, 20:34

Вы можете нажать Ctrl-Z, чтобы поместить задачу в фоновый режим. После этого вы можете работать в своей оболочке и просматривать историю команд. Для просмотра задач в фоновом режиме используйте команду job . Чтобы вернуться к своей задаче, выполните команду fg .

4
27.01.2020, 20:34

Вот как сgdb(вам нужно запустить его с правами администратора )черезhttps://stackoverflow.com/questions/7272558/can-we-define-a-new-data-type-in-a-gdb-session:

подготовка:

echo 'typedef void * histdata_t;
typedef struct _hist_entry {
  char *line;
  char *timestamp;
  histdata_t data;
} HIST_ENTRY;
typedef struct _hist_state {
  HIST_ENTRY **entries;
  int offset;
  int length;
  int size;
  int flags;
} HISTORY_STATE;
HIST_ENTRY _sampleentry;
HISTORY_STATE _samplestate;
' | tee sample.c
# get sample.o
gcc -g -c sample.c

# get bash pid, maybe via `pgrep bash`, or `pidof bash`, etc
# say in this example, it is 16573

Команда запуска теста:

$ sudo gdb -p 16573 -ex "set confirm off" -ex "add-symbol-file sample.o 0" -ex 'printf "ptype HIST_ENTRY\n"' -ex "ptype HIST_ENTRY" -ex 'printf "p *(HISTORY_STATE*)history_get_history_state()\n"' -ex 'p *(HISTORY_STATE*)history_get_history_state()' -ex 'set $myoffs = (*(HISTORY_STATE*)history_get_history_state())->offset' -ex 'printf "myoffs %d\n", $myoffs' -ex 'printf "p *(HIST_ENTRY *)history_get($myoffs)\n"' -ex 'p *(HIST_ENTRY *)history_get($myoffs)'
....
0x00007fb053abb0e9 in __pselect (nfds=1, readfds=0x7ffe81a009b0, writefds=0x0, exceptfds=0x0, 
    timeout=<optimized out>, sigmask=0x7ffe81a00930) at../sysdeps/unix/sysv/linux/pselect.c:69
69 ../sysdeps/unix/sysv/linux/pselect.c: No such file or directory.
add symbol table from file "sample.o" at
   .text_addr = 0x0
Reading symbols from sample.o...done.
ptype HIST_ENTRY
type = struct _hist_entry {
    char *line;
    char *timestamp;
    histdata_t data;
}
p *(HISTORY_STATE*)history_get_history_state()
$1 = {entries = 0x55ed117f4ab0, offset = 155, length = 155, size = 502, flags = 1}
myoffs 155
p *(HIST_ENTRY *)history_get($myoffs)
$2 = {line = 0x55ed119684d0 "kill -STOP $$", timestamp = 0x55ed119709a0 "#1545016332", data = 0x0}

подготовить команду gdb «захватить последнюю запись истории»:

echo '
set verbose off
set complaints 0
set trace-commands off
add-symbol-file sample.o 0
set $myoffs = ((HISTORY_STATE*)history_get_history_state())->offset
set $line = ((HIST_ENTRY *)history_get($myoffs))->line
printf "%s\n", $line
' | tee gdbscript

запустите команду gdb «захватить последнюю запись истории»:

sudo gdb -p 16573 -batch -x gdbscript 2>/dev/null | tail -1
kill -STOP $$
8
27.01.2020, 20:34

Теги

Похожие вопросы