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?

codeforester
  • 39,467
  • 16
  • 112
  • 140
kmad1729
  • 1,484
  • 1
  • 16
  • 20
  • 3
    Arguments come from the current shell, not the environment in which the command will eventually be run. – chepner Mar 07 '17 at 21:22

2 Answers2

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:

Community
  • 1
  • 1
codeforester
  • 39,467
  • 16
  • 112
  • 140
  • 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 Sep 02 '22 at 06: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

Ahsan Naseem
  • 1,046
  • 1
  • 19
  • 38