Помните, что расширение параметров не происходит волшебным образом, вам нужна оболочка, которая сделает это за вас.
var=3 /bin/echo `$var`
Я не уверен, что вы пытаетесь сделать с этим, назад -тики здесь не подходят (они выполняют команду и заменяются ее выводом ).
var=3 bash -c "/bin/echo '$var'"
не работает, потому что расширение параметра происходит до назначения, поэтому текущая оболочка заменяет "/bin/echo '$var'"
на /bin/echo ''
(, предполагая, что var
не определено ), а дочерняя оболочка запускается с
/bin/echo ''
Попробуйте
var=3 bash -c 'echo $var'
вместо :здесь одинарные кавычки защищают аргумент от текущей оболочки, а новая оболочка запускается с
echo $var
, который будет обработан так, как вы ожидаете.
Что касается вашего второго пункта, мой первоначальный комментарий остается в силе. Если вы хотите поиграть со средой и посмотреть, что произойдет, запустите env
и вместо этого отфильтруйте вывод:
var=3 env | grep var
var=3 exec env | grep var
Нет "системного вызова... для каждого регистра".
Интерфейс системного вызова зависит от аппаратной архитектуры. Часто (почти всегда? )случай, когда процесс сохраняет целое число, соответствующее требуемому системному вызову, в предварительно -определенном регистре, а затем выполняет инструкцию, которая запускает ЦП для передачи исполнения коду обработки системных вызовов ядра. Ядро обращается к предварительно определенному -регистру, чтобы определить, какой системный вызов запрашивает процесс, а затем выполняет соответствующий обработчик системного вызова.
Например, рассмотрим эту программу «hello world» в сборке x86 _64 для Linux:
$ cat hello.s
.text
.global
main:
movq $1, %rax # write() system call number
movq $1, %rdi # first parameter -- standard output file descriptor
movq $msg, %rsi # second parameter -- buffer
movq $14, %rdx # third parameter -- buffer length
syscall # invoke system call
movq $60, %rax # exit() system call number
movq $0, %rdi # first parameter -- exit status
syscall # invoke system call; this will never return
.section.rodata
msg:
.ascii "Hello, world!\n"
$ gcc hello.s
$./a.out
Hello, world!
$
Для x86 _64 номер системного вызова хранится в регистре rax
, первый параметр системного вызова хранится в rdi
, второй параметр системного вызова хранится в rsi
, а третий параметр хранится в rdx
.
Пример начинается с помещения значения 1
в регистр rax
. 1
— номер системного вызова для системного вызова write()
. Далее 1
помещается в регистр rdi
; 1
— дескриптор файла для стандартного вывода, а rdi
— регистр для первого параметра. Затем адрес msg
сохраняется в регистре rsi
; rsi
— второй параметр. Затем 14
сохраняется в rdx
; 14 — длина строки, а rdx
— регистр для третьего параметра. Затем инструкция syscall
запускает ЦП для передачи управления коду ядра. Ядро проверяет rax
,использует значение в этом регистре (1 ), чтобы определить, какой системный вызов следует выполнить (write ), а затем вызывает соответствующий обработчик.
Когда ядро завершает выполнение системного вызова, управление возвращает процесс пользовательского пространства. Он записывает 60
для регистрации rax
; снова rax
— регистр для номера системного вызова, а здесь 60
— номер системного вызова для exit()
. Записывает 0
в регистр rdi
— первый (и единственный )параметр системного вызова exit; статус выхода. Опять же, инструкция syscall
заставляет ЦП передать управление коду ядра. Ядро проверяет rax
, использует значение в этом регистре (60 ), чтобы определить, какой системный вызов следует выполнить (exit ), затем вызывает соответствующий обработчик. Обработчик exit()
завершает процесс, так что инструкция никогда не возвращается.
Примеры, выполняющие одну и ту же задачу, будут различаться в зависимости от аппаратной архитектуры; это даже не то же самое для 32 -бит Intel.