I have a question that may or may not have an answer in the form I am looking for, but any form will suffice.

I currently have a configuration file, in which I will use a shell command on that uses grep to find a specific line within the file, then I use sed to get all the text after a specific character. The remaining text is simply a file path that includes an environment variable. The output from the command returns something like this:


I then want to pipe that to mp3info to get usable meta data from the mp3 file. However, when I pipe that over to mp3info $LIGHTS_HOME doesn't expand to the actual file path it is correlated to. How can I expand it within one line? Is this even possible?

Here is my current command:

$ sudo grep -w "file_path =" /home/pi/lightshowpi/config/state.cfg | 
sed 's/.*= //' | sed  's|'\$LIGHTS_HOME'| '/home/pi/lightshowpi'|' |
xargs mp3info -p "Now Playing: %t by %a" | xargs sudo python /home/pi/lightshowpi/tweet/tweet.py

What the command is doing(I have edited the line so that it is easier to read, in use it will need to be a single line (preferably, I am open to multi line if needed):

the first line uses grep to find the line 'file_path =', which returns the line 'file_path = $LIGHTS_HOME/music/songname.mp3'

Which is then piped to sed which parses the statement and returns all characters after the '=', which returns in this case '$LIGHTS_HOME/music/songname.mp3'

From there I use a second sed command to replace $LIGHTS_HOME with its variable value '/home/pi/lightshowpi/'

Ideally I would like to get rid of this second sed statement in favor of something that evaluates '$LIGHTS_HOME' to its value '/home/pi/lightshowpi/'

Which will then be used by mp3info to get the meta data of the file, which is formatted as a stdout which then is piped to xargs which prepares the meta stdout into a stdin format that the python script uses and tweets the value with a few other emoticon characters (which the python script does without an issue)

However, instead of using a second sed command of substituting $LIGHTS_HOME for /home/pi/lightshowpi I would rather have $LIGHTS_HOME expanded since on other installations this variable could be set somewhere other than the home directory.

I think I should note, that I am trying this whilst in terminal, I am not putting this inside a shell script. I am unsure if that changes things, I am still doing my best to learn shell, but I believe that this may change things based on the errors I keep getting.

  • Thanks for the idea I will break it up and place a detailed description of what is needed. @thrig – Brett Reinhard Dec 5 '16 at 22:35
  • @don_crissti unfortunately the issue is that depending on the installation and setup $LIGHT_HOME could be /home/pi/lightshowpi or /root/some/other/directory – Brett Reinhard Dec 5 '16 at 23:54
  • @don_crissti this is going to be apart of an open source project and needs the functionality of being a universal command, and for inexplicable reasons would prefer to be a single line command unless it's not attainable and then could be manipulated into a sh script – Brett Reinhard Dec 5 '16 at 23:56
  • @don_crissti I'm sorry, this is what I was looking for, I somehow read the comment incorrectly. Your solution was clear, it was my problematic reading skills – Brett Reinhard Dec 6 '16 at 0:01
  • @don_crissti would you mind explaining how your suggested solution works? I mean Im all for working commands, but I would also like to understand what it is that is going on. mainly I am confused about /file_path =/!d;s|.*=||;s|\$LIGHTS_HOME|$LIGHTS_HOME|" given that 'file_path =' is within the state.cfg file I am assuming that this command with find 'file_path =' then return everything after it, then replace $LIGHTS_HOME with what I would believe is the expansion of $LIGHTS_HOME, for this example /home/pi/lightshowpi but would be /root/pi/lightshowpi for a different configured $LIGHTS_HOME – Brett Reinhard Dec 6 '16 at 0:16

With ZSH you can "perform parameter expansion, command substitution and arithmetic expansion" with the (e) parameter expansion flag on something in a given variable x (see zshexpn(1) for details):

x='$HOME/blablah'; echo $x; echo ${(e)x}

Or from a file:

echo '$HOME/fromfile' > afile
echo ${(e)$(<afile)}

This has various advantages over eval, depending on who has access to the configuration file and how naughty they are:

$ touch somefile
$ echo 'hi; rm somefile' > x
$ eval "echo `cat x`"       
$ ls somefile
ls: somefile: No such file or directory
$ exec zsh
% touch somefile
% echo ${(e)$(<x)}
hi; rm somefile
% ls somefile
  • So essentially I can have the first portion stored into X then type ; echo $x | mp3info and it would evaluate the $LIGHTS_HOME portion of the file path into the actual file path? – Brett Reinhard Dec 5 '16 at 21:35
  • I am thinking something along the lines of: filename = sudo grep -w "file_path =" /home/pi/lightshowpi/config/state.cfg | sed 's/.*= //' | sed 's|'\$LIGHTS_HOME'| '/home/pi/lightshowpi'|'; echo $filename | xargs mp3info -p "Now Playing: %t by %a" | sudo python /home/pi/lightshowpi/tweet/tweet.py would this be the proper usage you are suggesting? – Brett Reinhard Dec 5 '16 at 22:46
  • the command should be filename = sudo grep -w "file_path =" /home/pi/lightshowpi/config/state.cfg | sed 's/.*= //'; echo $filename | xargs mp3info -p "Now Playing: %t by %a" | sudo python /home/pi/lightshowpi/tweet/tweet.py however, when I tried this, i get the error filename: command not found – Brett Reinhard Dec 5 '16 at 22:55

Essentially, this line of code searches a configuration file /home/pi/lightshowpi/config/state.cfg for the line "file_path =" then expands the environment variable $SYNCHRONIZED_LIGHTS_HOME to its value and pipes it to mp3info which extracts the meta data from the MP3 file then pipes the string to a Python script that takes the arguments and removes unwanted characters while including emoticons from a Python emoji library to tweet to your account through twitters API.

sed '/file_path =/!d;s|.*= ||;s|$SYNCHRONIZED_LIGHTS_HOME|'"$SYNCHRONIZED_LIGHTS_HOME|" /home/pi/lightshowpi/config/state.cfg | xargs mp3info -p "Now Playing %t by %a" | xargs sudo python /home/pi/lightshowpi/tweet/tweet.py

The key to this command is using ! to exclude the 'file_path =' then using xargs for mp3info and tweet.py

I will be debugging the following /home/pi/lightshowpi/config/state.cfg use the same variable $SYNCHRONIZED_LIGHTS_HOME instead of /home/pi/lightshowpi to make this command universal for this open source project.


Assuming that you have the value $LIGHTS_HOME/music/something.mp3 in a variable $myvar

you can expand it via :

mp3info $(eval echo $myvar)
  • I have updated my question with my current command which works fine, but I'd rather have $LIGHTS_HOME expanded and I do not have it stored in a variable. – Brett Reinhard Dec 5 '16 at 21:30

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.