A non-root linux user owns a text file that's located in /etc, where the non-root linux user does not have permission to create files. The non-root linux user can edit the file manually via vi without issue. Programmatic and manual attempts to replace a text string within the file using sed -i, perl -i, and other in-directory temp file methods are failing due to permissions issues when the non-root linux user runs the text-replacement script. I've found a solution in the Perl Cookbook (noted farther down) but it has concerning warnings, plus it looks a bit beyond me at present. Can anyone suggest a simpler option?
Server Info:
cat /etc/os-release: Oracle Linux Server 8.9uname -a:Linux server01.domain.com 5.4.17-2136.322.6.4.el8uek.x86_64perl:
(v5.26.3) built for x86_64-linux-thread-multised:
(GNU sed) 4.5awk:
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)Location of file to edit:
/etcPermissions on
/etc:drwxr-xr-x 130 root root 12288 Jun 21 11:50 etcText file to edit:
/etc/targetfile-rw-rw-r-- 1 justauser group1 1864 Jun 19 10:52 targetfileFile length of
/etc/targetfilecan be as large as 200 lines that are about 50 characters each.
Example/abbreviated /etc/targetfile contents:
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
Goal: Programmatically change /dir1/dir2/59.35 to /dir1/dir2/59.77 in targetfile located in /etc, where the non-root user running the script is "justauser" who lacks permissions to create files in /etc.
Constraints:
- Permissions on /etc can't change.
- Existing server programs/utilities can't be upgraded.
- All programs/commands must be called from within a bash shell script.
- The bash shell script must be executed as "justauser", not as root.
- Not using sudo is strongly preferred.
Miscellaneous:
While logged in as the linux user "justauser", command line editing /etc/targetfile using vi works fine.
Commands like sed -i and perl -i fail since "justauser" lacks write perms in /etc to create temp files.
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
}
...
Options seen:
Perl Cookbook 7.10 Modifying a File in Place Without a Temporary File:
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."
Final Comments:
Is there an in-place edit option that doesn't use an in-directory temp file that is simpler than the Perl Cookbook example?
The Perl Cookbook example is a bit hard to follow for a Perl novice, and it also requires some kind of modification/conversion... I'd think...to work in the body of the bash script.
spongefrommoreutilsalready installed by any chance?vi /etc/filename -c s/xxx/yyy/ -c :wqwork?sed -iandperl -ido not edit a file; instead, they replace the file with a new one, which the user cannot create in that directory.