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 !

9
  • In FreeBSD bash is not installed by default, I would suggest using pure sh so you could make your script more portable. Commented Mar 18, 2019 at 9:24
  • @nbari What do you mean by pure sh ? Commented Mar 18, 2019 at 9:26
  • Check this answer stackoverflow.com/a/42666651/1135424 basically I mean to use only sh POSIX-compliant Commented Mar 18, 2019 at 9: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. Commented Mar 18, 2019 at 9:35
  • 1
    You may want to investigate the difference between cat << EOF and cat << \EOF. Commented Mar 18, 2019 at 9:43

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.