2

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.

Giacomo1968
59.1k23 gold badges180 silver badges225 bronze badges
asked Oct 15 at 12:43
5
  • 2
    Are you just trying to identify a specific argument, wherever it is in the overall command, and modify it? If so, please list those things you've tried using SED and AWK, so we don't misuse our own efforts and suggest things you've already tried. EDIT your question to clarify it, and use the formatting tools there in the post editor to make it more clear. Commented Oct 15 at 13:18
  • 2
    The script shall be static, it shall use -p "$(cat /path/to/password_file)" and the password shall be the only data in the password_file (protected by its mode or the mode of the to directory). Whenever you need to change the password for the script, you just update the whole password_file. It's quite easy to do this atomically and safely. I would create the to directory in a decent filesystem as accessible only for me (so I wouldn't need to separately protect every new file in it). Then printf '%s\n' 'p1wrd!cmd' > /path/to/new && mv /path/to/new /path/to/password_file should do. Commented Oct 15 at 14:10
  • 2
    Still the password passed as command line parameter may be visibile (in Linux use hidepid= to mitigate the problem). It would be nice if your command could read a password from a file or from a file descriptor on its own, not as an argument. Commented Oct 15 at 14:13
  • 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 result Commented Nov 16 at 18:10
  • To avoid nasty surprises, always quote your whell variables unless you need to unquote them, see mywiki.wooledge.org/Quotes. You should probably be using command -z "$ZONE" -a "$FQDN", instead of command -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. Commented Nov 17 at 0:31

2 Answers 2

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.

Peter Mortensen
12.3k24 gold badges74 silver badges93 bronze badges
answered Oct 15 at 13:58
2
  • For only selected lines (your second version) simpler '/^command /s/ -p [^ *]/ -p newpass/' Commented Oct 15 at 23:34
  • Those sed commands would do different things depending on the characters used in the new password which the OP said is stored in the variable NEWPASS. For example, try setting NEWPASS='a&b' or NEWPASS='a1円b' or NEWPASS='a/b' and then sed 's/ -p [^ ]*/ -p '"$NEWPASS"'/' toto1.sh or however you'd like to expand the shell variable. Commented Nov 16 at 23:10
0

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.

answered Nov 16 at 15:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.