3

I am scripting my new VM stack and I am trying to update or append JAVA_HOME in the ~/.bashrc file

I've managed to do that by running the following sed command from the command line.

sed '/export[ ]JAVA_HOME=/{h;s/=.*/='"updatedJava"'/};${x;/^$/{s//export JAVA_HOME='"newJava"'/;H};x}' -i ~/.bashrc

However, when I try to run it from a script using a variable, I am getting the following error:

sed: -e expression #1, char 34: unknown option to `s'

I figured out that it is caused due to fact that my path contain / which is confused with the sed delimiter, therefore I've changed it to this:

 sed '/export[ ]JAVA_HOME=/{h;s#=.*#='$java'#};${x;/^$/{s##export JAVA_HOME='$java'#;H};x}' -i ~/.bashrc

where $java contains a path to java, however now it doesn't work, it also doesn't throw any exception. Where did I make a mistake?

  • I want to check if there is already "export JAVA_HOME=" in .bashrc and update it with correct value (hold in $java variable) . In case it doesn't exist I want to append it to the file – Dawid Adach Jun 3 '17 at 20:30
2

Keeping your logic, I have recast the sed in a slightly compact form, wherein, the change to the JAVA_HOME is done once at the beginning of the sed.

Plus, there's this bit about escaping the java variable so that it is fit to be included into the rhs of a s/// sed command.

Plus, the sed is POSIX-ly.

java_esc=$(printf '%s\n' "$java" | sed -e 's|[\&/]|\\&|g;$!s/$/\\/')

sed -i.BAK -e '
   1{
      x
      s/.*/export JAVA_HOME='"$java_esc"'/
      x
   }

   # assuming the JAVA_HOME declaration does not span line boundaries
   /^[[:blank:]]*export[[:blank:]]\{1,\}JAVA_HOME=/{
      g
      x
      s/^/\
/
      x
   }

   ${
      x
      /^\n/!H
      x
   }
' ~/.bashrc
  • It's throwing "sed: can't read .BAK: No such file or directory" however it's doing the main job correctly – Dawid Adach Jun 6 '17 at 11:48
  • @DawidAdach Fixed. No space between i and backup extension. – user218374 Jun 6 '17 at 12:52
  • I have odd issue. After removing space as you suggested entire script stopped working :( what is even more surprising, once i revert to the previous version it doesn't append nor update the ~/.bashrc file. $java_esc echo shows correctly escaped path. Is it possible that it has something to do with BAK file? some file permissions? I separated only your code and java path (checked twice and it doesn't work anymore), any idea? (running as sudo) – Dawid Adach Jun 7 '17 at 20:14
  • OK, that's odd... I just found the answer. The reason was that I was runnig script with sudo. Without sudo it works like a charm and replaces everything... I am leaving second comment in case someone else face the same issue in a future – Dawid Adach Jun 7 '17 at 20:18
0

The second command has dropped the " characters from the replacement string. And I don't understand what you are doing with the s at the end, so how about:

sed '/export \{1,\}JAVA_HOME=/{h;s#=.*#="'$java'"#};${x;/^$/{s##export JAVA_HOME="'$java'"#;H};x}' -i ~/.bashrc
  • No result neither :( you can check yourself adding java="/sample/path/to/java" . JAVA_HOME= is not beeing appended to the file – Dawid Adach Jun 3 '17 at 20:29
  • Did it work for you? It still doesn't work for me :( I jus tried with no luck – Dawid Adach Jun 3 '17 at 20:51
  • I've set "export JAVA_HOME=temp" inside ~/.bashrc, unfortunately after running the script doesn't affect file – Dawid Adach Jun 3 '17 at 20:58
  • The + quantifier in /export +JAVA_HOME=/ isn't portable I don't think - (and where it is supported, it probably requires extended mode -E or -r) - try either /export *JAVA_HOME=/ (that's two spaces and a star) or /export \{1,\}JAVA_HOME=/ for one or more space characters – steeldriver Jun 3 '17 at 21:42
  • 1
    @DawidAdach, updated with comments. – Stephen Rauch Jun 3 '17 at 21:53

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.