Please note that I have done some search and tried different solutions with sed/awk and nothing worked. I'm stuck, so I posted the question here requesting your help.
Let’s say that there's a generic command in a script toto1.sh with variables like:
command -z $ZONE -a $FQDN -u serviceaccount -p p!ass@w0rq -c domainOrganizationUnit
I'd like to run a command (from a script update-pass.sh) that change the string after the parameter -p (the command do not know the string after the -p parameter) to something else (for example, to: p1wrd!cmd)
NEWPASS= p1wrd!cmd
We run something like sed/awk with $NEWPASS (the content contains the new value)
So after the execution of the command, the line becomes:
command -z $ZONE -a $FQDN -u serviceaccount -p p1wrd!cmd -c domainOrganizationUnit
Please note that there isn't any specific order in parameters, meaning -p is not necessarily at the fourth position. The command can be also be:
command -u serviceaccount -p p!ass@w0rq -z $ZONE -a $FQDN -c domainOrganizationUnit
The important thing is that the string after the -p parameter change.
2 Answers 2
For
$ cat toto1.sh
command -z $ZONE -a $FQDN -u serviceaccount -p p!ass@w0rq -c domainOrganizationUnit
command -u serviceaccount -p p!ass@w0rq -z $ZONE -a $FQDN -c domainOrganizationUnit
This
$ sed 's/ -p [^ ]*/ -p p1wrd!cmd/' toto1.sh
command -z $ZONE -a $FQDN -u serviceaccount -p p1wrd!cmd -c domainOrganizationUnit
command -u serviceaccount -p p1wrd!cmd -z $ZONE -a $FQDN -c domainOrganizationUnit
or to only change passwords for a specific command "command"
$ sed 's/^\(command.*\) -p [^ ]*/1円 -p p1wrd!cmd/' toto1.sh
command -z $ZONE -a $FQDN -u serviceaccount -p p1wrd!cmd -c domainOrganizationUnit
command -u serviceaccount -p p1wrd!cmd -z $ZONE -a $FQDN -c domainOrganizationUnit
This assumes old passwords never contain spaces and the commands are never continued across multiple lines etc. I would test carefully on a range of inputs and maybe insert code into toto1.sh that checks for and guards against syntax errors by checking return codes from commands.
The above is a literal-minded answer but I would advocate using the far less risky approach outlined in the comment by Kamil Maciorowski.
If toto1.sh is always used interactively, you could also consider having toto1.sh prompt for the password every time, using a method that doesn't display the password as it is typed.
-
For only selected lines (your second version) simpler
'/^command /s/ -p [^ *]/ -p newpass/'dave_thompson_085– dave_thompson_0852025年10月15日 23:34:36 +00:00Commented Oct 15 at 23:34 -
Those
sedcommands would do different things depending on the characters used in the new password which the OP said is stored in the variableNEWPASS. For example, try settingNEWPASS='a&b'orNEWPASS='a1円b'orNEWPASS='a/b'and thensed 's/ -p [^ ]*/ -p '"$NEWPASS"'/' toto1.shor however you'd like to expand the shell variable.Ed Morton– Ed Morton2025年11月16日 23:10:48 +00:00Commented Nov 16 at 23:10
Any attempt to use sed for this will be hampered by the fact that sed doesn't understand literal strings, e.g. try with &, /, or 1円 in your new password, and so the sed command or the string you want to use as the password will need to be modified based on whatever characters it contains. Not so with awk which understands literal strings:
$ newpass='a&b/c1円d'
$ printf '%s\n' "$newpass"
a&b/c1円d
$ newpass="$newpass" awk -v q="'" '
match(0,ドル/ -p [^ ]+/) {
0ドル = substr(0,1,ドルRSTART+3) q ENVIRON["newpass"] q substr(0,ドルRSTART+RLENGTH)
}
1' file
command -z $ZONE -a $FQDN -u serviceaccount -p 'a&b/c1円d' -c domainOrganizationUnit
See how-do-i-use-shell-variables-in-an-awk-script for how/why I'm using ENVIRON[] and setting NEWPASS to its existing value on the awk command line.
-p "$(cat /path/to/password_file)"and the password shall be the only data in thepassword_file(protected by its mode or the mode of thetodirectory). Whenever you need to change the password for the script, you just update the wholepassword_file. It's quite easy to do this atomically and safely. I would create thetodirectory in a decent filesystem as accessible only for me (so I wouldn't need to separately protect every new file in it). Thenprintf '%s\n' 'p1wrd!cmd' > /path/to/new && mv /path/to/new /path/to/password_fileshould do.hidepid=to mitigate the problem). It would be nice if yourcommandcould read a password from a file or from a file descriptor on its own, not as an argument.tried different solutions with sed/awk and nothing worked... please do not write a vague description like that ... instead, decribe what you tried and what was the resultcommand -z "$ZONE" -a "$FQDN", instead ofcommand -z $ZONE -a $FQDN. Using all upper case variable names is probably wrong in your code too, idk - see correct-bash-and-shell-script-variable-capitalization.