0

I have the following line in my .bashrc file:

cat "$HOME/.module_list" | while read m; do echo "Loading module $m..."; module load "$m"; done

where $HOME/.module_list is a file that contains the name of a module to load on each row. When .bashrc is sourced, the line goes through each module in the list one by one and seemingly loads them, but afterwards, when I do module list, none of the modules are loaded.

Does this line create a new scope into which the modules are loaded, which is then terminated as soon as the line finishes, or why aren't the modules still loaded afterwards? How can I successfully load all modules from the list and still have them be loaded afterwards?

HelloGoodbye
  • 3,624
  • 8
  • 42
  • 57
  • 2
    by default commands after the pipeline (`|`) would run in a subshell and its env would be gone when the `| command` completes. – sexpect - Expect for Shells Jun 07 '22 at 16:28
  • See [BashFAQ/024 (I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?)](https://mywiki.wooledge.org/BashFAQ/024). – pjh Jun 07 '22 at 16:39
  • Also see [Append to an array variable from a pipeline command](https://stackoverflow.com/q/37229058/4154375), [A variable modified inside a while loop is not remembered](https://stackoverflow.com/q/16854280/4154375), and [Capturing output of find . -print0 into a bash array](https://stackoverflow.com/q/1116992/4154375). – pjh Jun 07 '22 at 16:40

1 Answers1

1

A simple solution is to load your modules names into an array:

#!/bin/bash

readarray -t modules < ~/.module_list

module load "${modules[@]}"

An other solution is to use a while read loop, making sure to avoid the |:

#!/bin/bash

while IFS='' read -r m
do
    module load "$m"
done < ~/.module_list
Fravadona
  • 13,917
  • 1
  • 23
  • 35
  • Ok, thank you! In the second alternative, which command is it that gets `~/.module_list` as input? I'm not that familiar with the `<` syntax. – HelloGoodbye Jun 08 '22 at 07:45
  • The whole `while` loop (i.e. each command in it) will "share" the content of `~/.module_list` as input; in this aspect, it's 100% equivalent to `cat ~/.module_list | while` – Fravadona Jun 08 '22 at 08:36
  • Also, what is `IFS` in the second alternative? – HelloGoodbye Jun 09 '22 at 07:56
  • It's not really needed here, it's just a habit of mine. Setting `IFS` to the empty string in the `read` command is for making sure that the leading/trailing blanks characters are not stripped from the line – Fravadona Jun 09 '22 at 08:09