1

I'm trying to create a bash script in order to daemonized celeryd task. In my bash script, I need to create some files and add content. This content have a variable given by user named $app_name with read method and some others variables in the content.

Issue:

When I copy the content located in my bash script to the given path, it doesn't copy variables already present inside.

Example:

In my bash script I have :

########################
# Get application name #
########################

read -p "Define the application name (lowercase and without spaces): " app_name
echo "You defined the application name: $app_name"

############################################################
# Create service file /usr/local/etc/rc.d/celeryd_app_name #
############################################################

cat > /usr/local/etc/rc.d/celeryd_$app_name << EOF
#!/bin/sh
# =====================================================
#  celeryd_$app_name - Starts the Celery worker daemon.
# =====================================================
#
# :Usage: /etc/init.d/celeryd_$app_name {start|stop|force-reload|restart|try-restart|status}
# :Configuration file: /etc/default/celeryd_$app_name

### BEGIN INIT INFO
# Provides:          celeryd_$app_name
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
EOF

But if I open the created file I get:

### BEGIN INIT INFO
# Provides:          celeryd_$app_name
# Required-Start:    
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

It doesn't copy $network $local_fs $remote_fs which are present in the content.

There is another way to do that ?

Thank you !

Essex
  • 6,042
  • 11
  • 67
  • 139
  • In FreeBSD `bash` is not installed by default, I would suggest using pure `sh` so you could make your script more portable. – nbari Mar 18 '19 at 09:24
  • @nbari What do you mean by pure `sh` ? – Essex Mar 18 '19 at 09:26
  • Check this answer https://stackoverflow.com/a/42666651/1135424 basically I mean to use only `sh POSIX-compliant` – nbari Mar 18 '19 at 09:29
  • @nbari I read the answer. Ok but I don't understand why my bash script won't be pure `sh`. Furthermore I execute my script trough `sh celeryd.sh`. All things work fine, except the copy into files, it doesn't copy variables if they are not defined in my bash script. – Essex Mar 18 '19 at 09:35
  • I would suggest then to remove the bash tag and change the question title, is misleading, that way others could help you better. – nbari Mar 18 '19 at 09:38
  • 1
    You may want to investigate the difference between `cat << EOF` and `cat << \EOF`. – AlexP Mar 18 '19 at 09:43
  • @AlexP I will make some investigate with your answer. – Essex Mar 18 '19 at 09:47
  • @AlexP you're right it works fine ! But I don't find any documentations between both way to write `EOF` – Essex Mar 18 '19 at 10:38
  • *"I don't find any documentation":* The documentation of your shell, see under "here documents". It should describe the difference between using an unquoted and a quoted label. – AlexP Mar 18 '19 at 10:45

1 Answers1

4

What is happening is that the here document is expanding the variables and since they are not declared you are getting empty values, from the wiki:

By default, behavior is largely identical to the contents of double quotes: variable names are replaced by their values, commands within backticks are evaluated, etc

$ cat << EOF
> \$ Working dir "$PWD" `pwd`
> EOF
$ Working dir "/home/user" /home/user

This can be disabled by quoting any part of the label, which is then ended by the unquoted value; the behavior is essentially identical to that if the contents were enclosed in single quotes. Thus for example by setting it in single quotes:

$ cat << 'EOF'
> \$ Working dir "$PWD" `pwd`
> EOF
\$ Working dir "$PWD" `pwd`

So from your example, you could modify your script to be something like:

#!/bin/sh

cat << 'EOF' > /usr/local/etc/rc.d/celeryd_$app_name
#!/bin/sh
# =====================================================
#  celeryd_$app_name - Starts the Celery worker daemon.
# =====================================================
#
# :Usage: /etc/init.d/celeryd_$app_name {start|stop|force-reload|restart|try-restart|status}
# :Configuration file: /etc/default/celeryd_$app_name
### BEGIN INIT INFO
# Provides:          celeryd_$app_name
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
EOF

Which then will produce the output:

#!/bin/sh
# =====================================================
#  celeryd_$app_name - Starts the Celery worker daemon.
# =====================================================
#
# :Usage: /etc/init.d/celeryd_$app_name {start|stop|force-reload|restart|try-restart|status}
# :Configuration file: /etc/default/celeryd_$app_name
### BEGIN INIT INFO
# Provides:          celeryd_$app_name
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
nbari
  • 25,603
  • 10
  • 76
  • 131