0

I am to program a simple shell in linux that can implement various stuffs including environment variables. I tried printing these variables using getenv but I have some problems. getenv always return NULL even if the user types a correct variable like $HOME for example. Here is my code

int i = 0;
if(strcmp(cmdArgv[i], "echo") == 0){
                char *variable;
                for(i = 1; cmdArgv[i] != NULL; i++){
                    variable = getenv(cmdArgv[i]);
                    if(!variable){
                        puts("not a variable");
                           printf("%s ", cmdArgv[i]);
                        }else{
                            puts("a variable");
                            printf("%s ", variable);
                        }
                   }
                   printf("\n");
                   exit(0);
               }

It doesn't enter into the else condition. For example if the user types echo ls $HOME. This input is parsed into the cmdArgv which is a char **. Then the output I have is

not a variable
ls
not a variable
$HOME

BUT $HOME is a variable so maybe my implementation of getenv isn't right. Any ideas as to what seem to be the problem? Thanks.

mkab
  • 933
  • 4
  • 16
  • 31

1 Answers1

7

The variable is called HOME, not $HOME. (The latter is your shell's syntax for expanding the variable.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Just making it a little more obvious: getenv() accepts the environment variable without the $ sign. – Ram Nov 27 '11 at 23:36
  • @kerrek Oh yeah... you're right. I'll have to `putenv` VAR for $VAR to be a variable. I mixed the notion of having a `$` sign and not having it. I feel so stupid for seeing this. Thanks. – mkab Nov 27 '11 at 23:39
  • I have another question. Why is it that when you type `echo $HOME` in the linux terminal, it still treats it as a `HOME` variable? – mkab Nov 27 '11 at 23:43
  • @mkab: The variable is always called `HOME`. The dollar sign tells the shell that the next word is the name of a variable and makes it expand it. Try `echo HOME` to see the difference. – Kerrek SB Nov 27 '11 at 23:55
  • @mkab As it says in the answer, `$HOME` is the syntax used to expand a shell variable. "the linux terminal" is presumably running a linux shell, so when you type `"echo $HOME"`, the shell expands the HOME variable *before* invoking the echo command. Your "simple shell" isn't following this principle, it is expanding variables inside the echo command itself, which is not "simple" at all. – Jim Balter Nov 28 '11 at 00:00
  • 1
    @mkab 'I'll have to putenv VAR for $VAR to be a variable' -- no, if you putenv("VAR=foo"), then getenv("VAR") will return "foo". The '$' is, again, *shell* syntax. When you type $VAR somewhere on the command line (outside of single quotes), you are telling the shell to replace it with getenv("VAR"). – Jim Balter Nov 28 '11 at 00:07
  • @jim: So for my shell I'd have to treat the case when the user types `$HOME`? Like i'd have to manually separate the `$` from the rest of the variable? Or is there a function that does it already apart from `getenv`? – mkab Nov 28 '11 at 00:11
  • @mkab: You need to parse the input and find all `$` and see if they are not escaped or single-quoted and then look at the rest of the token(s) following to figure out what to expand them to. After this is done you execute the resulting line. I recommend you read the source of an existing shell, such as `ash`; it will be instructive. – sorpigal Nov 28 '11 at 11:40