首页 > 解决方案 > What is the function of this sed shell script?

问题描述

I was reading this example about setting up a cluster with pgpool and Watchdog and decided to give it a try as an exercise.

I'm far from being a master of shell scripting, but I could follow the documentation and modify it according to the settings of my virtual machines. But I don't get what is the purpose of the following snippet:

if [ ${PGVERSION} -ge 12 ]; then
    sed -i -e \"\\\$ainclude_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'\" \
           -e \"/^include_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'/d\" ${DEST_NODE_PGDATA}/postgresql.conf
fi

In my case PGVERSION will be 12 (so the script will execute the code after the condition), RECOVERYCONF is /usr/local/pgsql/data/myrecovery.conf and DEST_NODE_PGDATA is /usr/local/pgsql/data.

I get (please excuse and correct me if I'm wrong) that -e indicates that a script comes next, the $(some commands) part evaluates the expression and returns the result, and that the sed regular expression indicates that the '/'s will be replaced by \/ (forward slash and slash). What is puzzling me are the "\\\$ainclude_if_exists =" and "/^include_if_exists" parts, I don't know what they mean or what are they intended for, nor how they interact. Also, the -e after the first sed regular expression is confusing me.

If you are interested in the context, those commands are near the end of the /var/lib/pgsql/11/data/recovery_1st_stage example script.

Thanks in advance for your time.

标签: bashshellsed

解决方案


Here's a tiny representation of the same code:

sed -i -e '$amyvalue = foo' -e '/^myvalue = foo/d' myfile.txt

The first sed expression is:

$                  # On the last line        
 a                 # Append the following text
  myvalue = foo    # (text to be appended)

The second is:

/                  # On lines matching regex..
 ^myvalue = foo    # (regex to match)
               /   # (end of regex)
                d  # ..delete the line

So it deletes any myvalue = foo that may already exists, and then adds one such line at the end. The point is just to ensure that you have exactly one line, by A. adding the line if it's missing, B. not duplicate the line if it already exists.

The rest of the expression is merely complicated by the fact that this snippet uses variables and is embedded in a double quoted string that's being passed to a different host via ssh, and therefore requires some additional escaping both of the variables and of the quotes.


推荐阅读