BASH - commands string-like - bash

I am wondering if it is possible in BASH to use commands in this way:
lets take command pwd
Lets say I would like to have a variable comm="pwd" and then use it somewhere in program, but when I use it, I get the real pwd command output. Is this even possible?

It's pretty simple, you can just do:
comm='pwd'
# just execute
$comm
# fetch output into variable
output=$($comm)

Try doing this :
var=$(pwd)
The backquote (`) is used in the old-style command substitution, e.g.
foo=`command`
The
foo=$(command)
syntax is recommended instead. Backslash handling inside $() is less surprising, and $() is easier to nest. See http://mywiki.wooledge.org/BashFAQ/082

Yes, just surround the sub-command in backticks (the ` character):
comm=`pwd`

Related

Why are quotes preserved when using bash $() syntax, but not if executed manually?

I have the following bash script:
$ echo $(dotnet run --project Updater)
UPDATE_NEEDED='0' MD5_SUM="7e3ad68397421276a205ac5810063e0a"
$ export UPDATE_NEEDED='0' MD5_SUM="7e3ad68397421276a205ac5810063e0a"
$ echo $UPDATE_NEEDED
0
$ export $(dotnet run --project Updater)
$ echo $UPDATE_NEEDED
'0'
Why is it $UPDATE_NEEDED is 0 on the 3rd command, but '0' on the 5th command?
What would I need to do to get it to simply set 0? Using UPDATE_NEEDED=0 instead is not an option, as some of the other variables may contain a space (And I'd like to optimistically quote them to have it properly parse spaces).
Also, this is a bit of a XY problem. If anyone knows an easier way to export multiple variables from an executable that can be used later on in the bash script, that could also be useful.
To expand on the answer by Glenn:
When you write something like export UPDATE_NEEDED='0' in Bash code, this is 100% identical to export UPDATE_NEEDED=0. The quotes are used by Bash to parse the command expression, but they are then discarded immediately. Their only purpose is to prevent word splitting and to avoid having to escape special characters. In the same vein, the code fragment 'foo bar' is exactly identical to foo\ bar as far as Bash is concerned: both lead to space being treated as literal rather than as a word splitter.
Conversely, parameter expansion and command substitution follows different rules, and preserves literal quotes.
When you use eval, the command line arguments passed to eval are treated as if they were Bash code, and thus follow the same rules of expansion as regular Bash code, which leads to the same result as (1).
Apparently that Updater project is doing the equivalent of
echo "UPDATE_NEEDED=\'0\' MD5_SUM=\"7e3ad68397421276a205ac5810063e0a\""
It's explicitly outputting the quotes.
When you do export UPDATE_NEEDED='0' MD5_SUM="7e3ad68397421276a205ac5810063e0a",
bash will eventually remove the quotes before actually setting the variables.
I agree with #pynexj, eval is warranted here, although additional quoting is recommended:
eval export "$(dotnet ...)"

Nesting ${name:offset:length} and $() in zsh

In zsh, $() lets me run the command inside the parenthesis and get the stdout, and ${name:offset:length} lets me get a substring of the variable name. How can I nest the former inside the latter? As a concrete example, the following is valid.
base=$(basename $HOME) # basename of user home directory -- temporary
user3=${base:0:3} # first three letters of $base
But can the same thing be achieved without defining the temporary?
I know that user3=$(basename $HOME | cut -c 1-3) will do the trick, but I'm looking for a solution that doesn't use cut.
Double quotes around the command substitution should work:
user3=${"$(basename $HOME)":0:3}
Though, I'd be inclined to use zsh's :t modifier instead of basename:
${${HOME:t}:0:3}
The :offset:length form is only really there for bash compatibility. If you might have an old version of zsh you can also use the subscript form:
${${HOME:t}[0,3]}

No such file or directory when exporting files using bash script [duplicate]

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?
Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.
FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

How to create a file/directory from within a function in .bashrc [duplicate]

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?
Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.
FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

Including "cat" command in unix shell Here Document

I'm trying to create a Here Document which is a shell script that includes the cat command. Of course, it fails when encountering the 2nd cat. I'm performing a lot of substitutions as well, so can't use the "DOC" escape trick.
myfile="/tmp/myipaddr"
cat >/usr/bin/setIPaddress <<_DOC_
...
OUT=`cat $myfile`
...
_DOC_
I supposed I could echo into a file, but that seems kludgy and I have a lot of quotes and backticks I'd need to escape?!? Any other thoughts?
Suppose the file contains
hello world
As written, the script you generate will contain the line
OUT=hello world
because the command substitution is performed immediately.
At the very least, you need to quote the line in the here document as
OUT="`cat $myfile`"
I suspect what you want is to include the literal command substitution in the resulting shell script. To do that, you would want to quote the backticks to prevent them from being evaluated immediately. Better still, use the recommended form of command substitution, $(...), and quote the dollar sign.
cat >/usr/bin/setIPaddress <<_DOC_
...
OUT=\$(cat $myfile)
...
_DOC_
/usr/bin/setIPaddress will then include the line
OUT=$(cat /tmp/myipaddr)

Resources