4

I have a bunch of functions stored in ~/.bash_functions, which is sourced by ~/.bashrc on shell startup. The file exports all the functions like so:

# Find functions in this script based on a grep search, and export them.
grep ^'[[:alnum:]]' ~/.bash_functions |
  grep '()' |
  cut -d'(' -f1 | 
  while read function
do
  export -f "$function"
done
unset function

This works perfectly fine on a local shell, but not via SSH. None of the functions are actually exported (checked using declare -F). However, if I put echo "$function" into the loop, it prints all the function names, so I know the only part of the loop not working is the export line.

The functions get exported properly if I use export -f in the SSH session, or if I add an export -f line for each individual function in the file.

I'm using 14.04 with Bash 4.3.11, and the SSH client is Termux on Android.

Edit: Even if I add declare -F at the bottom of ~/.bash_functions, the functions show as not exported.

Edit: I just realized that in a local session, some of my functions aren't exported, seemingly at random, but I can't find any evidence of an error. I am doing more research...

5
  • Where this snippet is located? Why unset at the end (although only function, without $ does not make any sense here)?
    – heemayl
    Jul 27 '16 at 19:25
  • @heemayl The code snippet is at the bottom of ~/.bash_functions. If it were anywhere else it would fail because the functions weren't defined. The unset part works properly, don't worry about that.
    – wjandrea
    Jul 27 '16 at 19:32
  • Post the full snippet of ~/.bash_functions
    – heemayl
    Jul 27 '16 at 19:36
  • That is the full snippet. I'm not sure what you mean.
    – wjandrea
    Jul 27 '16 at 19:38
  • You said the functions are defined in ~/.bash_functions and you have this snippet on the same file?
    – heemayl
    Jul 27 '16 at 19:40
0

Because the while loop is in a pipeline, it is being executed in a subshell. If you log out and log in, you will see that a local session will be affected too (not just SSH). This can be fixed by moving the list into a variable and switching to a for loop:

# Find functions in this script based on a grep search, and export them.
functions="$( grep ^'[[:alnum:]]' ~/.bash_functions |
  grep '()' |
  cut -d'(' -f1 
)"

for function in $functions; do
  export -f "$function"
done
unset -v function functions # Also I added the -v flag to make this only unset variables.
10
  • This is incorrect. While you are sourcing files, it can travel any depth of subshells when constructing the environment. Create a file to source another file and in that file define a function and then use the while loop to read the function name and the export, you'll see.. Also you have put a misguided question at the first place..
    – heemayl
    Jul 28 '16 at 14:42
  • @heemayl Excuse me, but you haven't properly read my answer. I understand how sourcing works. I'm saying the loop is in a subshell. The issue is now resolved. And how can a question be misguided?
    – wjandrea
    Jul 28 '16 at 14:46
  • This works perfectly fine on a local shell, but not via SSH. this is a showkiller..
    – heemayl
    Jul 28 '16 at 14:47
  • Yes, i know the while loop is in a subshell, refer to my comment again and do the test please..
    – heemayl
    Jul 28 '16 at 14:49
  • @heemayl Yes, and I addressed that in my answer. "If you log out and log in, you will see that a local session will be affected too (not just SSH)." (I just edited the sentence.) Logging out and logging back in was not part of the troubleshooting I had tried already, and I had changed the way the export worked while logged in to that same session, so I hadn't noticed a change in local sessions yet.
    – wjandrea
    Jul 28 '16 at 14:51

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.