Как скопировать файлы / bin вместе с зависимостями с помощью команд?

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

Сравните вывод

$ strace -f /bin/bash -o trace.txt -c 'i=5; echo $i; echo file_c-$((++i)).txt; echo $i'
5
6
6

с

strace -f /bin/bash -o trace.txt -c 'i=5; echo $i; ls > file_c-$((++i)).txt; echo $i'
5
5

. Вы увидите в первом:

1251  execve("/bin/bash", ["/bin/bash", "-c", "i=5; echo $i; echo file_c-$(( ++"...], [/* 19 vars */]) = 0
...
1251  write(1, "5\n", 2)                = 2
1251  write(1, "file_c-6.txt\n", 13)    = 13
1251  write(1, "6\n", 2)                = 2

И во втором:

1258  execve("/bin/bash", ["/bin/bash", "-c", "i=5; echo $i; ls > file_c-$(( ++"...], [/* 19 vars */]) = 0
...
1258  write(1, "5\n", 2)                = 2
...
1258  stat("/bin/ls", {st_mode=S_IFREG|0755, st_size=110080, ...}) = 0
1258  access("/bin/ls", R_OK)           = 0
1258  clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7301f40a10) = 1259
1259  open("file_c-6.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
1259  dup2(3, 1)                        = 1
1259  close(3)                          = 0
1259  execve("/bin/ls", ["ls"], [/* 19 vars */]) = 0
1259  write(1, "71\nbin\nfile_a-5.txt\nfile_b-5.txt"..., 110) = 110
1259  close(1)                          = 0
1259  munmap(0x7f0e81c56000, 4096)      = 0
1259  close(2)                          = 0
1259  exit_group(0)                     = ?
1259  +++ exited with 0 +++
1258  <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1259
1258  rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f7301570d40}, {0x4438a0, [], SA_RESTORER, 0x7f7301570d40}, 8) = 0
1258  rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
1258  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1259, si_status=0, si_utime=0, si_stime=0} ---
1258  wait4(-1, 0x7ffd23d86e98, WNOHANG, NULL) = -1 ECHILD (No child processes)
1258  rt_sigreturn()                    = 0
1258  write(1, "5\n", 2)                = 2

В этом последнем примере вы видите клон в новый процесс (от 1258 до 1259), так что теперь мы находимся в подпроцессе. Открытие file_c-6.txt, что означает, что мы вычислили $ ((++ i)) в подоболочке, и выполнение ls с его стандартным выводом, установленным на это файл.

Наконец, мы видим, что подпроцесс завершается, мы пожинаем потомок, затем продолжаем с того места, где остановились ... с $ i , установленным в 5, и это то, что мы повторяем снова.

(Помните, что изменения переменных в подпроцессе не передаются родительскому процессу, если только вы не сделаете что-то явно в родительском для захвата изменений дочернего процесса)

0
11.04.2019, 14:41
1 ответ

Используйте cp -P (заглавную P ), чтобы переместить любую символическую ссылку и вместо этого скопировать символическую ссылку.

Это можно комбинировать с другими опциями, такими как -R для копирования иерархии каталогов — cp -RL проходит по всем символическим ссылкам на каталоги, cp -RP копирует все символические ссылки как таковые. cp -R может выполнять одно или другое действие в зависимости от вариантов Unix; GNU cp (, найденный в CentOS ), по умолчанию имеет значение -P.

Даже с помощью -P вы можете скопировать цель символической ссылки в каталог в командной строке, добавив / в конце :cp -RP foo/ bar копирует дерево каталогов, которое foo указывает на.

GNU cp имеет удобную -опцию, сочетающую в себе -R, -P, -p и немного больше. Он делает точную копию источника (, насколько это возможно ), сохраняя иерархию каталогов, символические ссылки, разрешения, время модификации и другие метаданные. общий флаг

2
28.01.2020, 02:40

Теги

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