I want to source a file in bash script. I know we can do -

. /path/to/file/file.cfg
source /path/to/file/file.cfg

But I am writing a single bash script in the world of Python scripts and need to use a config file created for Python scripts -

Python config file -

[section 1]

[section 2]

bash script -

source /path/to/python_config_file

echo $param1

Error I get -

/path/to/python_config_file: line 1: $'[section 1]\r': command not found

I tried to remove the [ ] lines -

source `sed -e 's/\[[^][]*\]//g' /path/to/python_config_file`
echo $param1

It dumps all the variables as output -

source $'\r' $'param1=val1\r' $'param2=val2\r' $'param1=val11\r' $'param2=val22\r'

: No such file or directory + echo

How do I resolve this? I know I can create a config file for bash but the issue is that the client doesn't want multiple config files as it'll become maintenance nightmare plus python + bash configs have to be synced.

  • Your file has CRLF line endings not standard LF endings. Convert it to unix style using unix2dos /path/to/python_config_file
    – Inian
    Apr 28 '20 at 13:19
  • 2
    The bigger problem I see is that bash's value for "param1" (for example) would be overwritten with the last value in the file; you haven't distinguished "section 1" from "section 2" & etc.
    – Jeff Schaller
    Apr 28 '20 at 13:25
  • Hi @Jeff, good catch! but this is temp file I had created quickly to demonstrate my problem.
    – sopana
    Apr 28 '20 at 13:32

First, you need to remove the Windows-style endings from your file. If you don't need to use the file on Windows, you can simply run dos2unix /path/to/file/file.cfg. Then, if you're using bash, you can use process substitution:

. <(grep = /path/to/file/file.cfg)

This will let you source only those lines of file.cfg that contain a =, which should be exactly what you need.

If you can't/don't want to modify the file to remove the \rs, you can do thsi when reading it instead:

. <(grep = /path/to/file/file.cfg | tr -d '\r')
  • Hi @terdon, thanks for the solution. It worked!
    – sopana
    Apr 28 '20 at 13:36
  • Hi @terdon, I think I'm facing the issue what Jeff has pointed out so is it possible to read only the lines after a particular section - [section 1] or [section 2]. If I supply the section name while executing the bash script?
    – sopana
    Apr 29 '20 at 6:28
  • @sopana that's a considerably more complicated question. Can't you just change the names of the config variables so they are not repeated? Make it section1_param1 instead of param1? You can't use source to get different values into a variable of the same name. So if you can't change the names, then please ask a new question explaining the entire situation.
    – terdon
    Apr 30 '20 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.