Open editor from bash script and cat file to variable not working - linux

Why doesn't this work? There has to be a very simple answer to this.
I have two bash scripts. The first script calls the second which opens an editor on a tmp file, once user quits, cat the file which will be assigned to a variable in the first script.
test-use-editor
#!/bin/bash
test=$(use-editor)
echo $test
use-editor
#!/bin/bash
TMP_MSG="/tmp/tmp_msg"
$EDITOR $TMP_MSG
cat $TMP_MSG
rm $TMP_MSG
If I call use-editor without assigning and $() the editor opens just fine, but if I try to assign it to $test it just hangs. The editor does start because I can see it in my processes, but it's in a subshell or something. How can I get it to open within the terminal which called the first script?

You need to pass tty on to use-editor, as thatotherguy suggested.
test-use-editor
#!/usr/bin/env bash
test=$(./use-editor $(tty))
echo $test
use-editor
#!/usr/bin/env bash
TTY=${1:-/dev/tty}
TMP_MSG="/tmp/tmp_msg"
$EDITOR $TMP_MSG < $TTY >& $TTY
cat $TMP_MSG
rm $TMP_MSG

Related

bash command working from terminal but not from script [duplicate]

a.sh
#! /bin/sh
export x=/usr/local
we can do source ./a in command-line. But I need to do the export through shell script.
b.sh
#! /bin/sh
. ~/a.sh
no error... but $x in command-line will show nothing. So it didn't get export.
Any idea how to make it work?
a.sh
#! /bin/sh
export x=/usr/local
-----------
admin#client: ./a.sh
admin#client: echo $x
admin#client: <insert ....>
You can put export statements in a shell script and then use the 'source' command to execute it in the current process:
source a.sh
You can't do an export through a shell script, because a shell script runs in a child shell process, and only children of the child shell would inherit the export.
The reason for using source is to have the current shell execute the commands
It's very common to place export commands in a file such as .bashrc which a bash will source on startup (or similar files for other shells)
Another idea is that you could create a shell script which generates an export command as it's output:
shell$ cat > script.sh
#!/bin/sh
echo export foo=bar
^D
chmod u+x script.sh
And then have the current shell execute that output
shell$ `./script.sh`
shell$ echo $foo
bar
shell$ /bin/sh
$ echo $foo
bar
(note above that the invocation of the script is surrounded by backticks, to cause the shell to execute the output of the script)
Answering my own question here, using the answers above: if I have more than one related variable to export which use the same value as part of each export, I can do this:
#!/bin/bash
export TEST_EXPORT=$1
export TEST_EXPORT_2=$1_2
export TEST_EXPORT_TWICE=$1_$1
and save as e.g. ~/Desktop/TEST_EXPORTING
and finally $chmod +x ~/Desktop/TEST_EXPORTING
--
After that, running it with source ~/Desktop/TEST_EXPORTING bob
and then checking with export | grep bob should show what you expect.
Exporting a variable into the environment only makes that variable visible to child processes. There is no way for a child to modify the environment of its parent.
Another way you can do it (to steal/expound upon the idea above), is to put the script in ~/bin and make sure ~/bin is in your PATH. Then you can access your variable globally. This is just an example I use to compile my Go source code which needs the GOPATH variable to point to the current directory (assuming you're in the directory you need to compile your source code from):
From ~/bin/GOPATH:
#!/bin/bash
echo declare -x GOPATH=$(pwd)
Then you just do:
#> $(GOPATH)
So you can now use $(GOPATH) from within your other scripts too, such as custom build scripts which can automatically invoke this variable and declare it on the fly thanks to $(pwd).
script1.sh
shell_ppid=$PPID
shell_epoch=$(grep se.exec_start "/proc/${shell_ppid}/sched" | sed 's/[[:space:]]//g' | cut -f2 -d: | cut -f1 -d.)
now_epoch=$(($(date +%s%N)/1000000))
shell_start=$(( (now_epoch - shell_epoch)/1000 ))
env_md5=$(md5sum <<<"${shell_ppid}-${shell_start}"| sed 's/[[:space:]]//g' | cut -f1 -d-)
tmp_dir="/tmp/ToD-env-${env_md5}"
mkdir -p "${tmp_dir}"
ENV_PROPS="${tmp_dir}/.env"
echo "FOO=BAR" > "${ENV_PROPS}"
script2.sh
shell_ppid=$PPID
shell_epoch=$(grep se.exec_start "/proc/${shell_ppid}/sched" | sed 's/[[:space:]]//g' | cut -f2 -d: | cut -f1 -d.)
now_epoch=$(($(date +%s%N)/1000000))
shell_start=$(( (now_epoch - shell_epoch)/1000 ))
env_md5=$(md5sum <<<"${shell_ppid}-${shell_start}"| sed 's/[[:space:]]//g' | cut -f1 -d-)
tmp_dir="/tmp/ToD-env-${env_md5}"
mkdir -p "${tmp_dir}"
ENV_PROPS="${tmp_dir}/.env"
source "${ENV_PROPS}"
echo $FOO
./script1.sh
./script2.sh
BAR
It persists for the scripts run in the same parent shell, and it prevents collisions.

Bash: Creating a shell variable in a bash script that I can access from command line

I have very little experience working with bash. With that being said I need to create a bash script that takes your current directory path and saves it to a shell variable. I then need to be able to type "echo $shellvariable" and have that output the directory that I saved to that variable in the bash script. This is what I have so far.
#!/bin/bash
mypath=$(pwd)
cd $1
echo $mypath
exec bash
now when I go to command line and type "echo $mypath" it outputs nothing.
You can just run source <file_with_your_vars>, this will load your variables in yours script or command line session.
> cat source_vars.sh
my_var="value_of_my_var"
> echo $my_var
> source source_vars.sh
> echo $my_var
value_of_my_var
You have to export the variable for it to exist in the newly-execed shell:
#!/bin/bash
export mypath=$(pwd)
cd $1
echo $mypath
exec bash
Hello
'env -i' gives control what vars a shell/programm get...
#!/bin/bash
mypath=$(pwd)
cd $1
echo $mypath
env -i mypath=${mypath} exec bash
...i.e. with minimal environment.

Bash script tee command syntax issue

I want to echo the following line at the end of ~/.profile file using tee command:
export PATH="$HOME/.local/bin:$PATH"
To do this my bash script looks like this
#!/bin/bash
path_env="export PATH="$HOME/.local/bin:$PATH""
echo $path_env| sudo tee -a $HOME/.profile > /dev/null
But whenever I am executing the script it is also executing $PATH and $HOME value and inserts that in ~./profile file which I do not want. I only want the exact line to be passed by the bash script instead of replacing $PATH and $HOME with its own values.
I only want the exact line to be passed by the bash script instead of replacing $PATH and $HOME with its own values.
Och, right, so do not expand it. Quoting.
path_env='export PATH="$HOME/.local/bin:$PATH"'
echo "$path_env" | sudo tee -a "$HOME/.profile" > /dev/null

command to redirect output to console and to a file at the same time works fine in bash. But how do i make it work in korn shell(ksh)

command to redirect output to console and to a file at the same time works fine in bash. But how do i make it work in korn shell(ksh).
All my scripts runs on korn shell so cant change them to bash for this particular command to work.
exec > >(tee -a $LOGFILE) 2>&1
In the code beneath I use the variable logfile, lowercase is better.
You can try something like
touch "${logfile}"
tail -f "${logfile}"&
tailpid=$!
trap 'kill -9 ${tailpid}' EXIT INT TERM
exec 1>"${logfile}" 2>&1
A not too unreasonable technique is to re-exec the shell with output to tee. That is, at the top of the script, do something like:
#!/bin/sh
test -z "$REXEC" && { REXEC=1 exec "$0" "$#" | tee -a $LOGFILE; exit; }

How to execute commands read from the txt file using shell? [duplicate]

This question already has answers here:
Run bash commands from txt file
(4 answers)
Closed 4 years ago.
I tried to execute commands read it from txt file. But only 1st command is executing, after that script is terminated. My script file name is shellEx.sh is follows:
echo "pwd" > temp.txt
echo "ls" >> temp.txt
exec < temp.txt
while read line
do
exec $line
done
echo "printed"
if I keep echo in the place of exec, just it prints both pwd and ls. But i want to execute pwd and ls one by one.
o/p am getting is:
$ bash shellEx.sh
/c/Users/Aditya Gudipati/Desktop
But after pwd, ls also need to execute for me.
Anyone can please give better solution for this?
exec in bash is meant in the Unix sense where it means "stop running this program and start running another instead". This is why your script exits.
If you want to execute line as a shell command, you can use:
line="find . | wc -l"
eval "$line"
($line by itself will not allow using pipes, quotes, expansions or other shell syntax)
To execute the entire file including multiline commands, use one of:
source ./myfile # keep variables, allow exiting script
bash myfile # discard variables, limit exit to myfile
A file with one valid command per line is itself a shell script. Just use the . command to execute it in the current shell.
$ echo "pwd" > temp.txt
$ echo "ls" >> temp.txt
$ . temp.txt

Resources