Um usuário Linux não root possui um arquivo de texto localizado em /etc
, onde o usuário Linux não root não tem permissão para criar arquivos. O usuário Linux não root pode editar o arquivo manualmente via vi sem problemas. Tentativas programáticas e manuais de substituir uma string de texto dentro do arquivo usando sed -i
, perl -i
e outros métodos de arquivo temporário no diretório estão falhando devido a problemas de permissão quando o usuário Linux não-root executa o script de substituição de texto. Encontrei uma solução no Perl Cookbook (anotado mais abaixo), mas ela contém avisos preocupantes, além de parecer um pouco além de mim no momento. Alguém pode sugerir uma opção mais simples?
Informações do servidor:
cat /etc/os-release
: Servidor Oracle Linux 8.9uname -a
:Linux server01.domain.com 5.4.17-2136.322.6.4.el8uek.x86_64
perl:
(v5.26.3) built for x86_64-linux-thread-multi
sed:
(GNU sed) 4.5
estranho:
GNU Awk 4.2.1, API: 2.0 (GNU MPFR 3.1.6-p2, GNU MP 6.1.2)
vi:
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Aug 5 2022 07:42:15)
Localização do arquivo a ser editado:
/etc
Permissões em
/etc
:drwxr-xr-x 130 root root 12288 Jun 21 11:50 etc
Arquivo de texto para editar:
/etc/targetfile
-rw-rw-r-- 1 justauser group1 1864 Jun 19 10:52 targetfile
O comprimento do arquivo
/etc/targetfile
pode chegar a 200 linhas com cerca de 50 caracteres cada.
Exemplo/ /etc/targetfile
conteúdo abreviado:
f1112:/dir1/dir2/59.35:N # Comment
f3332:/dir1/dir2/59.35:N # Comment
f4442:/dir1/dir2/59.35:N # Comment
f555:/dir1/dir2/59.35:N # Comment
f666s2:/dir1/dir2/59.35:N # Comment
f777s2:/dir1/dir2/59.35:N # Comment
Objetivo: Alterar programaticamente /dir1/dir2/59.35 para /dir1/dir2/59.77 no arquivo de destino localizado em /etc, onde o usuário não root que executa o script é "justauser" que não tem permissão para criar arquivos em /etc.
Restrições:
- As permissões em /etc não podem ser alteradas.
- Os programas/utilitários de servidor existentes não podem ser atualizados.
- Todos os programas/comandos devem ser chamados de dentro de um script shell bash.
- O script shell bash deve ser executado como "justauser", não como root.
- Não usar o sudo é fortemente preferido.
Diversos:
Enquanto estiver logado como usuário Linux "justauser", a edição da linha de comando /etc/targetfile
usando vi funciona bem. Comandos como sed -i
e perl -i
falham, pois "justauser" não possui permissões de gravação em /etc para criar arquivos temporários.
perl -i -p -e 's/f4442:\/dir1\/dir2\/59.35:N/f4442:\/dir1\/dir2\/59.77:N/g' /etc/targetfile
--Can't remove /etc/targetfile: Permission denied, skipping file.
sed -i 's/f4442:\/dir1\/dir2\/59.35:N/f4442:\/dir1\/dir2\/59.77:N/' /etc/targetfile
--sed: sed: couldn't open temporary file /etc/sedO2SLSF: Permission denied
Rough Intended Usage Example (static values replacing variables to come):
#!/bin/bash
...
function _editConfig {
echo "Editing targetfile..."
perl -i -p -e 's/f4442:\/dir1\/dir2\/59.35:N/f4442:\/dir1\/dir2\/59.77:N/g' /etc/targetfile
if [ $? -ne 0 ]
then
echo "Error on _editConfig function.\n Terminating program"
EXITCODE=1
fi
}
...
Opções vistas:
Perl Cookbook 7.10 Modificando um arquivo no local sem um arquivo temporário:
open(F, "+< $infile") or die "can't read $infile: $!";
$out = '';
while (<F>) {
s/DATE/localtime/eg;
$out .= $_;
}
seek(F, 0, 0) or die "can't seek to start of $infile: $!";
print F $out or die "can't print to $infile: $!";
truncate(F, tell(F)) or die "can't truncate $infile: $!";
close(F) or die "can't close $infile: $!";
...
"This approach is for the truly determined.
It's harder to write, takes more memory (potentially a lot more),
doesn't keep a backup file,
and may confuse other processes trying
to read from the file you're updating.
For most purposes, therefore, we suggest it's probably not worth it."
Comentários finais:
Existe uma opção de edição local que não usa um arquivo temporário no diretório que seja mais simples que o exemplo do Perl Cookbook?
O exemplo do Perl Cookbook é um pouco difícil de seguir para um novato em Perl e também requer algum tipo de modificação/conversão... eu acho... para trabalhar no corpo do script bash.