So I think what is tripping you here is the command format where the first word(s) in the command are a variable assignment (which the shell determines based on the presence of a =.)
In those cases, the shell will evaluate those assignments, but it will only export those variables in the command that it is running. In particular, the shell itself won't have access to those variables.
This is useful for running commands or scripts that are affected by environment variables, in which case you don't need to export them in a shell and can just set them as "one-offs" for that single execution.
Let's break down your commands and explain them one by one:
pwd echo 'aaa' # /home/me
Ok, so this is running the pwd command and passing it two arguments, echo and aaa. But pwd doesn't take arguments, so it's just ignoring those two and printing the local directory.
val=pwd echo 'aaa' # aaa
So as I explained, this performs the variable assignment, setting $val to contain the string pwd and then executes the echo command with the aaa argument. The $val variable is available only to the echo command and not to the shell itself! The echo command doesn't really do anything with that variable, so it simply goes ahead and prints aaa. After this command is finished, the $val variable is not defined in the shell.
val=pwd echo 'aaa'$val # aaa
So, again, similar to the command above. This one gets tricky, since you might expect the final $val to get expanded. But variables are expanded by the shell, not by the commands. And, as explained, the shell doesn't really see $val which is set to pwd, only the command (in this case, echo) does, so $val gets expanded to an empty string, and this is exactly equivalent to the above.
val=pwd echo 'aaa' && echo $val # aaa <and an empty line>
And one more time, $val is not available after the first echo command completes, so the second echo $val will print nothing (just the blank line), as $val was never really set in the shell itself throughout this execution.
If you want to set $val in the shell, then you need to make that assignment a standalone, without any commands. For instance, this behaves differently from the above:
$ val=pwd; echo 'aaa' && echo $val
aaa
pwd
Since val=pwd is followed by a ;, then the shell considers it a command on its own and will set $val in the current shell, so the echo $val will work as you expect.
(Note that there's one more difference here, since with val=pwd; ..., the variable $val is not really exported, so echo will not see that variable in its environment, while with val=pwd echo ... it would get exported, but then in that case, it is not available in the shell.)
And considering you're using pwd, I wonder if what you wanted was to store the output of that command in the variable... In which case, you need to use shell command substitution, either using backticks, or better yet, surrounding the command with $( and ).
So one final example here:
$ val=$(pwd); echo 'aaa' && echo $val
aaa
/home/me
Or:
$ val=$(pwd) && echo 'aaa' && echo $val
aaa
/home/me
(There's a subtle difference here, where the latter will break execution if the command inside the substitution, in this case pwd, fails and exits with a non-zero status, in which case the following commands will not be executed. When using ; that's not the case, the following commands are executed even if the first one fails.)
I hope this explains what you weren't understanding about these commands!
&&. – Gordon Davisson Jul 26 '18 at 06:36pwd(with too many arguments). The rest is a syntax error due to the unterminated command substitution (unbalanced backticks). (Now edited by Filipe Brandenburger). – Kusalananda Jul 26 '18 at 06:45setup.sh, you will get what I posed here... Seriously I got no idea why it wrote such a code. – Yves Jul 26 '18 at 07:11