4

A couple of days ago I came across a command

AWS_ACCESS_KEY="foo" AWS_SECRET_KEY="bar" aws list iam

I see that setting variables before a command adds those variables in the command's environment:

#make sure there is no environment variable "foo"
$ echo $foo

#mimic-ing above command
$ foo=bar printenv | grep foo
foo=bar

#or trying from python environment
$foo=bar python -c "import os; print(os.getenv('foo', None))"
bar

#foo is destroyed now
$ echo $foo  
#<<NOTHING

I was trying to use this trick to dynamically create a new directory based on today's date:

$ dname=$(date +%d_%m_%y) mkdir ${dname} && cd ${dname}

but I got following error:

mkdir: missing operand
Try 'mkdir --help' for more information.

i.e. dname=$(date +%d_%m_%y) echo $dname returns empty!

What am I doing wrong? How can I dynamically create and use are variable on the same line in bash?

1
  • 3
    Arguments come from the current shell, not the environment in which the command will eventually be run.
    – chepner
    Commented Mar 7, 2017 at 21:22

2 Answers 2

5

Shell is substituting your variable before running the command inside $(). You can use && to make it work for you:

dname=$(date +%d_%m_%y) && mkdir ${dname} && cd ${dname}

or, of course:

dname=$(date +%d_%m_%y); mkdir ${dname} && cd ${dname}

However, dname would be available to mkdir if it were to grab the environment variable inside.

Let's say we have a script test.sh that has a single statement echo $dname inside. Then:

dname=$(date +%d_%m_%y) ./test.sh

would yield:

07_03_17

This is consistent with how your aws command line worked.


Similar posts:

1
  • This is different in that it sets dname for the remainder of this script (or until explicitly unset, of course). Perhaps in practice you would want to define a function which does mkdir "$1" && cd "$1" and then call it with your value as its argument.
    – tripleee
    Commented Sep 2, 2022 at 6:21
0

you are missing && before mkdir below is complete statement you desire:

dname=$(date +%d_%m_%y) && mkdir ${dname} && cd ${dname}

Also if its not necessary to declare dname you can do: mkdir $(date +%d_%m_%y) && cd ${dname} both will give same answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.