Skip Navigation
Linux 101 stuff. Questions are encouraged, noobs are welcome! @lemmy.world Samueru @lemmy.ml

How can I turn this shell script into a single line command?

Here is the script, which is a hack that I use with i3wm, I already converted most of it to a single line and it still works:

#!/usr/bin/env bash

is-leaf-node() { i3-msg -t get_tree | jq 'recurse(.nodes[]?, .floating_nodes[]?) | select(.type == "con" or .type == "floating_con") | select(.focused == true) | .nodes == []';}; parent-type() { i3-msg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.nodes[]?.focused == true) | .type' ;}; if [ "$(is-leaf-node)" == "true" ]; then i3-msg focus parent, focus parent; else i3-msg focus child, focus child; fi

Here is where I'm stuck:

The script needs the #!/usr/bin/env bash to work, it is the only script that I have that needs it.

Changing it to #!/usr/bin/env bash; <SCRIPT> does not work, it has have a second line for it to work.

3

You're viewing a single thread.

3 comments
  • Judging by the first line, this script is a set of Bash commands.

    If this line is there, when the script is executed it will run as a Bash script.

    This line is required for it to work as a Bash script; if it isn't there, it will execute using the kernel, and it won't work because it's not a binary program.

    If you want it all in one line, just copy and paste it into a terminal that already runs Bash, and exclude the first line. But why do you want it in one line in the first place? Multiline scripts have no performance drop, and they are more readable.

    • I think this is a limitation of i3, because I also had a similar issue with another script.

      For example on my polybar I have this when changing the volume:

      scroll-up = pulsemixer --change-volume +5 --unmute --max-volume 100 &amp;&amp; pactl list sinks | awk '/State: /{flag=1} /dB/ &amp;&amp; flag {printf("%.0fdB", $7); exit}' | xargs -I {} dunstify -r 11 -t 1000 "Main Vol: {}"
      
      scroll-down = pulsemixer --change-volume -5 --unmute --max-volume 100 &amp;&amp; pactl list sinks | awk '/State: /{flag=1} /dB/ &amp;&amp; flag {printf("%.0fdB", $7); exit}' | xargs -I {} dunstify -r 11 -t 1000 "Main Vol: {}"
      

      It has no problems running, however I also wanted to do the same with i3 when I press the volume keys on my keyboard and i3 can't do it, I had to make it a script file and point i3 to it for it to work.

      But why do you want it in one line in the first place? Multiline scripts have no performance drop, and they are more readable.

      I prefer to have all i3 settings on one config file, that is easier for me, it is just one file that I need to backup and also one file that I need to edit when changing things.

      On ther other hand if the scripts are their on individual files, I have to make sure that the script has the permission to run, put the script on its place, etc.

      I also have a keybind to open my i3config so I can do quick changes to it on the fly, while if every script had its own file I would need to navigate thru each one individually.

      For example I recently began testing voidlinux and on void my monitors have different names than on arch, so my i3config didn't work by just being dropped in I had to edit the file.

      To do so I just told mousepad to find all instances where the name DP-1 is and replace it for DisplayPort-0, same for DP-2 to Display-Port-1, etc, etc.

      If my monitor settings had been its own script file that i3 ran, I would have also needed to open it and edit it.

      That is why I would prefer to have the scripts on the i3config, not a big deal but if it is possible I would like to know for the cases where it doesn't work.