sed -i "1 i\<records>$(wc -l Final.txt < Final.txt)</records>" Final.txt
No necesita una variable intermedia.
Edite :Por usuario kamaraj y por usuario DonChrissti comentó y eliminó la afirmación de que necesita el comando cut
, o alguna otra forma de analizar el nombre del archivo que wc
genera junto con el número de líneas. Una simple redirección de E/S oculta eso de wc
, por lo que sin saber qué archivo se está procesando, no tiene nada que imprimir.
Что изменилось, так это то, что /bin/sh
либо стал bash
, либо остался dash
, который получил дополнительный флаг -p
, имитирующий поведение bash.
Bash требует, чтобы флаг -p
не сбрасывал привилегию setuid, как объяснено на его справочной странице :
If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.
Раньше dash
не заботился об этом и разрешал выполнение setuid (, ничего не делая для его предотвращения ). Но на справочной странице Ubuntu 16.04 dash
описана дополнительная опция, похожая наbash
:
-p priv
Do not attempt to reset effective uid if it does not match uid. This is not set by default to help avoid incorrect usage by setuid root programs via system(3) or popen(3).
Этой опции не существовало в основной ветке разработки (, которая могла не реагировать на предложенный патч*)или в Debian 9, но присутствует в Debian buster, который получил патч с 2018 года.
ПРИМЕЧАНИЕ. :как объяснил Stéphane Chazelas, слишком поздно вызывать "/bin/sh -p"
в system()
, потому что system()
запускает все, что передается через /bin/sh
, поэтому setuid уже отброшен. Ответ derobert объясняет, как справиться с этим в коде до system()
.
Вероятно, оболочка по той или иной причине меняет свой эффективный идентификатор пользователя обратно на реальный идентификатор пользователя в процессе запуска. Вы можете проверить это, добавив:
/* needs _GNU_SOURCE; non-Linux users see setregid/setreuid instead */
uid_t euid = geteuid(), egid = getegid();
setresgid(egid, egid, egid);
setresuid(euid, euid, euid);
перед вашим system()
. (На самом деле, даже в Linux вам, вероятно, нужно установить только настоящие; сохраненные должны быть в порядке, чтобы оставить в покое. Это просто грубая сила для отладки. В зависимости от того, почему вы установили идентификатор -, вам, конечно, может понадобиться где-то сохранить настоящие идентификаторы.)
[Кроме того, если это не просто упражнение по изучению того, как работает setid, то существует множество проблем безопасности, о которых нужно беспокоиться, особенно при вызове оболочки. Например, существует множество переменных среды, влияющих на поведение оболочки. Предпочитайте уже -существующий подход, такой как sudo
, если это вообще возможно.]