2

Trying to test something and not quite nailing it either way I've tried, so not sure if I'm being silly or not.

Essentially I need to parse a string to ipa-getcert's post-save argument which should include the year of the certificate renewal. This means the script will run once to request the certificate and then the current year can be used (simple). But then when ipa-getcert renews a certificate it will run a command with arguments post-save, and it's at this time that the year of the renewal must be used. The whole string to get a certificate issued including the post-save option [-C] is:

sudo ipa-getcert request -N $CERT_CN -K HTTP/$CERT_CN -k /etc/ssl/private/${CERT_CN}.key -f /etc/ssl/certs/${CERT_CN}.crt \
-D $CERT_CN -C "$INST_CERT -n ${CERT_NAME}_"'$(date +"%Y")'" $INST_OPTS $PAN_MGMT"

Attempting to test this I tried the following, but the date is never expanded. Is there a better way to test this, apart from using ipa-getcert to test?

$ txt="The year is: "
$ echo $txt$(date +"%Y")
The year is: 2023
$ echo $txt'$(date +"%Y")'
The year is: $(date +"%Y")
$ echo $(echo $txt'$(date +"%Y")')
The year is: $(date +"%Y")

But echoing the string does, so the single quotes seem to remain even when not printed on screen.

$ echo The year is: $(date +"%Y")
The year is: 2023

Undoubtedly I'm missing something trivial here.

[EDIT:] But then the following works fine, so maybe I'm just paranoid?

$ mkdir $(date +"%Y")
$ test2="ll "'$(date +"%Y")'
$ echo $test2
ll $(date +"%Y")
$ eval $test2
total 8
drwxrwxr-x  2 user group 4096 Apr 24 20:01 ./
drwxr-xr-x 13 user group 4096 Apr 24 20:01 ../
  • Please [edit] your question and show us what the expected output is, so we can understand which part of this is confusing you. In the case of the simple examples you show, when would you expect expansion? How would you want this to behave? – terdon Apr 24 '23 at 17:57
  • What's the reason behind you wanting to put a command into a string variable? – Chris Davies Apr 24 '23 at 18:08
  • @terdon I want getcert to be able to issue a command to install a certificate with a name containing the year at the time of renewal. Typical examples are for locally used certificates where the names of the files don't change and a systemctl restart xyz.service is enough.

    Hence I want to be able to parse a string like: -C "pan_instcert -n fw.local.local_$(date +"%Y") fw.local.local without the date being interpreted when the command is executed that takes this string.

    – dmgeurts Apr 24 '23 at 21:44
  • @roaima I can rework my code without using a variable for the string, which will probably be the easiest way of doing this... – dmgeurts Apr 24 '23 at 21:49

2 Answers2

4

The shell doesn't parse the results of expansions for shell syntax. It's not plain text-replacement in that way. This is true for quotes, other expansions, shell operators and shell keywords, none of those are recognized from the result of an expansion. So if the variable contains a dollar sign and some parenthesis, then you get a dollar sign and some parenthesis.

If you want the expansion to happen at run-time, store the command in a function instead:

renew() {
    "$INST_CERT" -n "${CERT_NAME}_$(date +"%Y")" $INST_OPTS "$PAN_MGMT"
}

Take care to quote the variables you expand there, or if you're relying on word splitting, take more care to be sure it does what you want.

Related / see also: How can we run a command stored in a variable?

ilkkachu
  • 138,973
  • I've seen that as a suggestion, but the final execution isn't inside this particular script. It's parsed to getcert which will execute the string given as a command at time the certificate is up for renewal. – dmgeurts Apr 24 '23 at 21:46
  • @dmgeurts please add all these details, including your answer to my comment, to your question. They are very relevant. That said, you can export the function or just define it in your script. – terdon Apr 24 '23 at 21:56
  • @terdon Some more detail added, thank you for your time. – dmgeurts Apr 24 '23 at 22:56
  • @dmgeurts, oh for crying out loud. – ilkkachu Apr 25 '23 at 05:30
0

I think that you need to remove the quotes like this:

RENEW_CMD="$INST_CERT -n ${CERT_NAME}_$(date +%Y) $INST_OPTS $PAN_MGMT"

Example:

FILE="example"
FILE2="year"
RND="randomvar"
REZ="$FILE ${FILE2}_$(date +%Y) $RND" 
echo "$REZ"

Result:

example year_2023 randomvar
  • 1
    that will expand the command substitution right at the assignment (which they likely didn't want since they explicitly mentioned protecting it with single quotes, etc., even though the example of date +%Y in particular probably will give the same value later in the script, too...) – ilkkachu Apr 24 '23 at 19:12
  • Precisely, the date can't be today's date as getcert will rerun it at set intervals and thus the date needs to change. – dmgeurts Apr 24 '23 at 21:51