Unable to store python --version to a shell variable [duplicate] - bash

This question already has answers here:
How to append output of "python --version" to a file in bash shell?
(2 answers)
Closed 8 years ago.
I need to get the version of Python installed and store it in a variable for later use. Whereas it is printing on the console instead of storing to variable. I am able to store output of ls command in a variable. Please check the below code :
root#myhost:/volumes/srini# cat python_version.sh
python_version=`python --version`
echo "\****"
echo $python_verison
echo "\****"
ls_output=`ls -l python*`
echo "\****"
echo $ls_output
echo "\****"
Please check the output of the code :
root#myhost:/volumes/srini# ./python_version.sh
Python 2.6.8
\****
\****
\****
-rwxr-xr-x 1 root root 147 May 26 09:35 python_version.sh
\****

Seems like that value gets sent to stderr for some reason, as in this question.
I find that the following seems to work:
python_version=$(python --version 2>&1)
echo "\****"
echo $python_version
echo "\****"
gives
\****
Python 2.7.3
\****

The value of python_version is set locally when the script is run. It has no impact on the invoking shell. If you want that variable to be set in the current shell, you can accomplish that using one of the following methods.
Run the following command in your current shell.
python_version=$(python --version 2>&1)
Create a file that contains the above line. Say that file is python_version.sh. Then execute:
source python_vesion.sh

Related

Multiple output with bash command

I want to find the 2 version of python. If I write:
{python2,python3}" --version; "
I am expecting it to run:
python2 --version; python3 --version;
and provide me the versions like if I would have written the above line directly :
Python 2.7.18
Python 3.8.10
but instead I get:
python2 --version;: command not found
even though if I test the output with:
echo {python2,python3}" --version"
I do get the expected:
python2 --version; python3 --version;
Trying
`echo {python2,python3}" --version"`
didn't work either.
Why? How do I make it work?
Because that's not what it does. You are creating two quoted strings "python2 --version; " and "python3 --version; " neither of which is a valid command. You could get around that with eval but ... that way lies madness.
# XXX DON'T
eval python{2,3}" --version;"
2.7.18
Python 3.8.10
The (not so) simple but straightforward solution would be something like
for v in 2 3; do
python$v --version
done
or if you are hellbent on using a wildcard, run a subshell:
echo python{2,3}" --version;" | bash
Perhaps notice the (lack of) difference between
echo python2" --version; "
and
echo "python2 --version; "
The quotes simply tell the shell to keep things together as a single string. (For what it's worth, the shell removes the quotes as part of its parsing process, so the argument to echo does not contain any actual quotes, just the parsed string from between the quotes.)
It's possible to have command names with literal spaces in them, but incredibly cumbersome; so you don't see this much in practice.
For fun, maybe try
# Have a directory in your PATH which is in your home directory
# If you don't, maybe create $HOME/bin and add it to your PATH
bash$ echo "$PATH" | tr ':' '\n' | grep "$HOME"
/users/you/bin
bash$ cat >"$HOME/bin/python2 --version"
#!/bin/sh
exec python2 --version
^D
bash$ chmod +x "$HOME/bin/python2 --version"
bash$ "python2 --version"
2.7.18
(Maybe delete the script when you're done experimenting.)

Grep and other programs not found in script [duplicate]

This question already has answers here:
"ls: not found" after running "read PATH"
(2 answers)
Getting "command not found" error in bash script
(6 answers)
Closed 12 months ago.
I am trying to gather all of my TODOs and make one file out of them.
#!/bin/bash
# Script for getting all TODOS
PATH="~/documents/obsidian-notes/"
OUTPUT="/home/fish/documents/obsidian-notes/TODO.md"
echo "#TODO" > $OUTPUT
grep -hr --exclude-dir=plugins "\bTODO\b:.*" $PATH | awk '{print $0,"\n"}' >> $OUTPUT
If I run each line in my prompt it works perfectly. When I add them to a script and make it executable and run it I get
./obtodo.sh: line 10: grep: command not found
./obtodo.sh: line 10: awk: command not found
./obtodo.sh: line 12: chown: command not found
I tried running as sudo and I made the script executable with chmod a+x
$PATH is a special variable to the shell. It defines the list of directories to be searched when executing subcommands.
Bash won't know where grep, awk or chown are. Please use different variable name instead of $PATH.
Try
#!/bin/bash
# Script for getting all TODOS
xPATH="~/documents/obsidian-notes/"
OUTPUT="/home/fish/documents/obsidian-notes/TODO.md"
echo "#TODO" > $OUTPUT
grep -hr --exclude-dir=plugins "\bTODO\b:.*" $xPATH | awk '{print $0,"\n"}' >> $OUTPUT

Unable to cat a data file into a script file (bash) on terminal command line [duplicate]

This question already has answers here:
Terminal - command not found
(2 answers)
Closed 3 years ago.
Im new to bash, and I am unable to cat a file and use the pipe command on the terminal using bash.
This is what ive tried on the terminal command line
$ cat data | readlooptest
however i always get this message when i use the pipe |
-bash: readlooptest: command not found
I have a Script named readlooptest, and a data file
script contents of readlooptest
#!/bin/bash
read myLine
sum=0
for i in $myLine
do
sum=`expr $sum + $i`
done
echo "sum is: $sum"
data file contents are
6 4 4 7 7
So once the commands are entered in terminal, the output should be
$ chmod +x readlooptest
$ cat data | readlooptest
sum is : 28
However I get
-bash: readlooptest: command not found
If readlooptest is not installed in one of your $PATH directories, you have to give the path to it to run it.
So for your piped cat, if you are cd in the same directory as readlooptest:
cat data | ./readlooptest
This has nothing to do with piping or cat. The actual problem is that you need to specify where readlooptest is, since it's not in your PATH. If it's in the working directory, simply add ./ to the start:
$ cat data | ./readlooptest

How to "hide" an executable from a bash script?

I want to test the output of a bash script when one of the executables it depends on is missing, so I want to run that script with the dependency "hidden" but no others. PATH= ./script isn't an option because the script needs to run other executables before it reaches the statement I want to test. Is there a way of "hiding" an executable from a script without altering the filesystem?
For a concrete example, I want to run this script but hide the git executable (which is its main dependency) from it so that I can test its output under these conditions.
You can use the builtin command, hash:
hash [-r] [-p filename] [-dt] [name]
Each time hash is invoked, it remembers the full pathnames of the commands specified as name arguments, so they need not be searched for on subsequent invocations. ... The -p option inhibits the path search, and filename is used as the location of name. ... The -d option causes the shell to forget the remembered location of each name.
By passing a non-existent file to the -p option, it will be as if the command can't be found (although it can still be accessed by the full path). Passing -d undoes the effect.
$ hash -p /dev/null/git git
$ git --version
bash: /dev/null/git: command not found
$ /usr/bin/git --version
git version 1.9.5
$ hash -d git
$ git --version
git version 1.9.5
Add a function named git
git() { false; }
That will "hide" the git command
To copy #npostavs's idea, you can still get to the "real" git with the command builtin:
command git --version
Since we know the program is running in bash, one solution is to - instead of "hiding" the program - emulate the behaviour of bash in this circumstance. We can find out what bash does when a command isn't found quite easily:
$ bash
$ not-a-command > stdout 2> stderr
$ echo $?
127
$ cat stdout
$ cat stderr
bash: not-a-command: command not found
We can then write this behaviour to a script with the executable name, such as git in the question's example:
$ echo 'echo >&2 "bash: git: command not found" && exit 127' > git
$ chmod +x git
$ PATH="$PWD:$PATH" git
$ echo $?
127
$ cat stdout
$ cat stderr
bash: git: command not found

Shell Scripting - Must not generate extra messages and its not but says I am

There is a similar question about this issue. But not the same solution.
I am to create a shell script that takes two parameters:
1.the desired file extension
2.the name of a single file to be renamed with that extension
The script should rename the file with the desired file extension. If the file does not exist, it should print out "fileName: No such file". It is producing this message but the professor's tests says it is producing unexpected messages(extra messages) but it is not. My shell script is:
#!/bin/sh
fileExtension="$1"
shift
oldName="${#}"
extension=${oldName##*.}
if test -r "$oldName"
then
if "$fileExtension" == $oldName.*
then
echo "$oldName"
else
newName="${oldName%.*}.$fileExtension"
mv "$oldName" "$newName"
fi
else
echo "$oldName": No such file
fi
Everytime I test it, it produces "fileName: no such file" and nothing else.
The test is executed by
./chExt2.sh cpp aardvark.CPP
where aardvark.CPP is not on the directory.
Any help or guidance would be much appreciated. Thank you
Your shebang is telling your shell to use /bin/sh to run the script. /bin/sh is typically a symlink to the real/default shell on the host. For example, mine's bash:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 27 2009 /bin/sh -> bash
It sounds like your professor's computer's /bin/sh is using a different shell than you are [expecting]. This script runs fine in ksh or bash, for example, but produces "extra output" if /bin/sh is tcsh:
fileExtension=cpp: Command not found.
Illegal variable name.

Resources