0

When I put a command on terminal, it works just fine, but when I put the same command in a .sh script and then run it, it doesn't give any output. What might be the reason for this?

The command:

IFS=$'\t'; while read -r k v; do 
    export "$k=\"$v\""
Qirohchan
  • 1,057
  • 1
  • 9
  • 15
  • `When I put the exact command in a .sh script` : Do you have a shebang for the script or are you just `sourcing` it? Please read [\[ this \]](https://stackoverflow.com/questions/496702/can-a-shell-script-set-environment-variables-of-the-calling-shell). – sjsam Jan 25 '18 at 09:36
  • You have edited out some of the code so that this is no longer valid Bash. The actual code is still available from the [edit history](https://stackoverflow.com/posts/48439370/revisions). – tripleee Jan 29 '18 at 06:09
  • Possible duplicate of https://stackoverflow.com/questions/16217064/change-environment-variable-in-child-process-bash – tripleee Jan 29 '18 at 06:11

2 Answers2

0

This is kind of expected since export sets the environment variable for that particular shell.

Docs -

export command is used to export a variable or function to the environment of all the child processes running in the current shell. export -f functionname # exports a function in the current shell. It exports a variable or function with a value.

So when you create a sh script it runs the specified commands into a different shell which terminates once the script exits.

It works with the sh script too -

data.sh

#!/bin/bash

IFS=$'\t'; while read -r k v; do 
    export "$k=\"$v\""
    echo $HELLO1
    echo $SAMPLEKEY
done < <(jq -r '.data | to_entries[] | [(.key|ascii_upcase), .value] | @tsv' data.json)

Output -

$ ./data.sh
"world1"

"world1"
"samplevalue"

Which suggests that your variables are getting exported but for that particular shell env.

In case you want to make them persistent, try putting scripts or exporting them via ~/.bashrc OR ~/.profile.

Once you put them in ~/.bashrc OR ~/.profile, you will find the output something as below -

I used ~/.bash_profile on my MAC OS -

Last login: Thu Jan 25 15:15:42 on ttys006
"world1"

"world1"
"samplevalue"
viveky4d4v@020:~$ echo $SAMPLEKEY
"samplevalue"
viveky4d4v@020:~$ echo $HELLO1
"world1"
viveky4d4v@020:~$ 

Which clarifies that your env variables will get exported whenever you open a new shell, the logic for this lies in .bashrc (https://unix.stackexchange.com/questions/129143/what-is-the-purpose-of-bashrc-and-how-does-it-work)

Put your script as it is ~/.bashrc at the end -

IFS=$'\t'; while read -r k v; do 
    export "$k=\"$v\""
    echo $HELLO1
    echo $SAMPLEKEY
done < <(jq -r '.data | to_entries[] | [(.key|ascii_upcase), .value] | @tsv' data.json)

You need to make sure that data.json stays in user's home directory.

vivekyad4v
  • 13,321
  • 4
  • 55
  • 63
0

Basically: A child process can't change the environment of it's parent process.

You need to source the script instead of executing it:

source your_script.sh

source runs the script in the current shell which makes it possible to modify the environment.


Alternatively you can create a function in your shell startup files (e.g. ~/.bashrc):

my_function() {
    IFS=$'\t'; while read -r k v; do 
        export "$k=\"$v\""
    done < <(jq -r '.data | to_entries[] | [(.key|ascii_upcase), .value] | @tsv' /path/to/data.json)
}

After you've started a new shell you can run

my_function
hek2mgl
  • 152,036
  • 28
  • 249
  • 266