В своем обновлении вы упомянули, что вы начинаете xterm
с xbindkeys
, и поскольку вы запускаете
xbindkeys && ssh-agent awesome
bindkeys
не будет иметь среды, связанной с SSH -, и, как следствие, xterm
тоже не будет.
Чтобы решить эту проблему, я бы предложил
eval "$(ssh-agent)"
xbindkeys && awesome
Теперь это установит переменные для xbindkeys
и awesome
(, которые вполне могут быть тем, что вам нужно и нужно ), но это не приведет к автоматическому завершению процесса ssh-agent
при выходе из системы.
Для этого вы можете использовать (с bash
),
eval "$(ssh-agent)"
trap 'eval "$(ssh-agent -k)"' EXIT
xbindkeys && awesome
или что-то подобное. Это вызовет ssh-agent -k
, который убьет агента, как только эта оболочка выйдет или будет завершена TERM
, HUP
или INT
.
Выполнение eval
на выходе ssh-agent -k
просто сбросит переменные SSH -, и это может быть не нужно (, так как скрипт все равно вот-вот завершится ), так что ловушка может быть настроен для запуска только ssh-agent -k >/dev/null
.
То, что ssh-agent
является дочерним процессом команды, который запускается сразу , выглядит странно.
ssh-agent
разветвляет фактический процесс агента, а затем заменяет исходный процесс командой, которую он должен запускать (с помощьюexec()
). В результате исходный процесс(xterm
во втором дереве процессов )является родителем агента :
/*
* Fork, and have the parent execute the command, if any, or present
* the socket data. The child continues as the authentication agent.
*/
if (D_flag || d_flag) {
log_init(__progname,
d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
SYSLOG_FACILITY_AUTH, 1);
format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
SSH_AUTHSOCKET_ENV_NAME);
printf("echo Agent pid %ld;\n", (long)parent_pid);
fflush(stdout);
goto skip;
}
pid = fork();
if (pid == -1) {
perror("fork");
cleanup_exit(1);
}
if (pid != 0) { /* Parent - execute the given command. */
close(sock);
snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
if (ac == 0) {
format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
SSH_AUTHSOCKET_ENV_NAME);
printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,
SSH_AGENTPID_ENV_NAME);
printf("echo Agent pid %ld;\n", (long)pid);
exit(0);
}
if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
perror("setenv");
exit(1);
}
execvp(av[0], av);
perror(av[0]);
exit(1);
}
(затем дочерний процесс продолжает выполнение остальной части кода)
Это позволяет вам убить агента без особых последствий, например, для команды, которую вы хотите запустить.
Предположим, что ваши данные выглядят так:
Id,name,currency
101,aaa,10000
102,BBB,
103,ccc,20000
Затем вы можете распечатать строки, которые не содержат данных в 3-м поле, используя
$ awk -F, '$3 == ""' file.csv
102,BBB,
-F,
в командной строке устанавливает разделитель полей ввода в виде запятой, поэтому awk
будет разделять каждую строку запятыми на отдельные поля. Условие $3 == ""
означает «поле 3 пусто» (, а «пусто» означает «даже не содержит пробела» ), и если это истинно , то действие по умолчанию будет быть принятым. Действие по умолчанию — напечатать текущую строку.
Хотите также вывести строку заголовка?:
$ awk -F, 'NR == 1 || $3 == ""' file.csv
Id,name,currency
102,BBB,
Условие NR == 1 || $3 == ""
означает "если это первая строка, или если 3-е поле пусто".
Если вы хотите добавить номер строки к каждой строке вывода, используйте
$ awk -F, 'NR == 1 || $3 == "" { print NR, $0 }' file.csv
1 Id,name,currency
3 102,BBB,
Здесь вместо действия по умолчанию мы запускаем блок, который печатает номер текущей строки(NR
)вместе с исходной строкой текста из файла($0
).
grep -n "null-(blank)" file.txt
выводит каждую строку (с номером строки ), где встречается «ноль -(пробел )»
Чтобы просто проверить столбец валюты, вы можете использовать следующий шаблон регулярного выражения:
grep -n "[^,]*,[^,]*,[ ]*null-(blank)" file.txt