Важно понимать, что каждый процесс имеет свой собственный набор переменных окружения.
Когда процесс вызывает системный вызов fork()
, создается второй процесс (дочерний), идентичный первому (родительскому) (эта копия включает окружение, которое находится чуть выше стека (или чуть ниже, в зависимости от того, как вы думаете о стеках : -)
- но в unix/linux стек растет вниз с высоких адресов).
Обычно дочерний процесс затем вызывает системный вызов execve()
, который отбрасывает все в его (виртуальной) памяти и восстанавливает ее из секций кода и данных в указанном двоичном файле.
Однако, когда он восстанавливает стек, он сначала (в таком порядке) копирует в стек окружение и строки аргументов, переданные в execve()
, перед вызовом функции main()
(большая часть работы выполняется в crt0
bootstrap-коде после возврата execve()
(в точку входа, указанную в бинарном файле)).
В библиотеке Си есть обертки для системного вызова execve()
, которые передают текущее окружение (т.е. копию родительского окружения), вместо того, чтобы вызывающая сторона предоставляла его (таким образом, фактически дочерняя программа наследует окружение родителя) - смотрите environ(7)
.
Попробуйте выполнить (от имени root) команду ps axeww | less
... это покажет вам окружение для всех процессов! Интересным является процесс с идентификатором 1 (т.е. init
- первый процесс, созданный ядром при загрузке).
Если вы хотите посмотреть окружение для определенного процесса (и знаете его идентификатор), попробуйте выполнить команду cat /proc/
(заменив
на идентификатор процесса).
Обратите внимание, что если процесс имеет достаточно привилегий, он может переписать свой собственный стек, что может затруднить определение его окружения - вы увидите некоторые процессы-демоны, подобные этому, в выводе ps.
Но в конце концов, вся эта вафля сводится к тому, что @chaos сказал выше: если вы хотите посмотреть текущее значение конкретной переменной окружения в вашем shell-процессе, просто используйте (встроенную) команду echo "$
(заменив
именем интересующей вас переменной окружения) ... только имейте в виду, что та же переменная может иметь другое значение или вообще не существовать в другом процессе.
Puede dejar las líneas que comienzan con A1
como están y volver a organizar -las que comienzan conB1
# if -E or -r is not supported: sed 's/\(B1:.*\)\(A1:.*\)/\2 \1/' ip.txt
$ sed -E 's/(B1:.*)(A1:.*)/\2 \1/' ip.txt
A1: abc.com B1: Hi there
A1: gml.com B1: Your Test mail
A1: hml.com B1: Your new mail
A1: def.com B1: Test email
A1: yml.com B1: hello world
.*
es codicioso, por lo que esta solución asume que A1:
y B1:
son únicos en cada línea (B1:.*)(A1:.*)
son dos grupos de captura -para satisfacer la expresión completa, el primero capturará todas las cadenas desde B1:
hasta justo antes de A1:
. El segundo capturará la cadena desde A1:
hasta el final de la línea \2 \1
re -organizar las cadenas capturadas con espacio entre ellas
conawk
$ awk -F'A1:' '{print $1 ~ /B1:/ ? FS $2 " " $1 : $0}' ip.txt
A1: abc.com B1: Hi there
A1: gml.com B1: Your Test mail
A1: hml.com B1: Your new mail
A1: def.com B1: Test email
A1: yml.com B1: hello world
Si el primer campo contiene B1:
, vuelva a -organizar los campos, de lo contrario, imprima la línea de entrada como está
Podemos hacer esto usando el siguiente método:
perl -F'/(A1:|B1:)/' -lane '
my %h = @F[1..$#F];
print map { "$_$h{$_} " } qw/A1: B1:/;
' input.txt
Salida:
A1: gml.com B1: Your Test mail
A1: abc.com B1: Hi there
A1: hml.com B1: Your new mail
A1: def.com B1: Test email
A1: yml.com B1: hello world
Explicación: