Home > Mobile >  Cd command not working in my implementation of a pipe
Cd command not working in my implementation of a pipe

Time:02-03

I'm trying to build pipex and i'm testing it with built-in command like "type" , but it seem to not work like the original with cd

<a.txt ls | cd > b.txt

So this code above is in shell and it change the directory to the home directory

And this one is about how i go about executing shell command on my code ,

execve("/bin/bash", arg2, NULL);

where arg2 is a matrix taking four param : bash,-c,cd,NULL

I've tried

execve("/usr/bin/cd",arg2,NULL);

the arg2 take : cd, param of cd, NULL

but it not changing the directory like the original one(i'm working on MACOS)

how should i go about that?

CodePudding user response:

it change the directory to the home directory

Yes, but only for the subshell. The parent shell will be unaffected.

cd /tmp
ls | cd
pwd                 # still /tmp
ls | ( cd ; pwd )   # this will output home dir, only for the duration of subshell as part of the pipe

This behavior can be changed by shell extensions, specifically by running the last part of the pipeline as part of current shell. In Zsh this is the default. In Bash this can be done with shopt -s lastpipe. See https://mywiki.wooledge.org/BashFAQ/024 . This is an extension to POSIX standard shell. It may be possible that your shell acts that way, but not all do.

how should i go about that?

 execve("/usr/bin/cd",arg2,NULL);

cd is a shell built-in, not a program. You have to detect that user specifically typed cd with like strcmp(command, "cd") and then execute custom code that set's the current working directory chdir(arg1); from inside your program. This is not an external program - it's part of your program.

To affect current process, do not fork() when executing the rightmost command of the pipeline, just let it affect the current execution environment.

CodePudding user response:

cd is not a program you can find in /usr/bin (not in /bin, nor in /usr/local/bin) but a shell internal command. It needs to be so, as the current dir is a property of each process (every process has its own current dir and root_dir) and, to change it, the only means is that the process itself calls the chdir(2) system call. No process can change the working directory of another (except if someone has recently invented a system call to do it). Changing another process current working directory should be very dangerous for the good working of the process itself.

If you call a process to chdir somewhere, the process changes its own current directory, but not the one of the parent, so the net effect is that you see no change when the subprocess returns. I can illustrate this by just asking you to execute the following shell code:

sh <<EOF
cd /tmp        # change to /tmp dir
echo "process \$\$ in dir \`pwd\`"
EOF
echo "process $$ in dir `pwd`"

in the first line the shell is given a small script through its standard input with an in-place file, extending upto the EOF token, to make it change dir to /tmp and print the current working directory after that (the backticks must be escaped to pass them to the subshell without interpretation in this shell)

If you put this shell code in a file (chdir.sh) and execute several times with the command

$ . chdir.sh
process 6602 in dir /tmp
process 5126 in dir /home/lcu
$ . chdir.sh
process 6604 in dir /tmp
process 5126 in dir /home/lcu
$ . chdir.sh
process 6606 in dir /tmp
process 5126 in dir /home/lcu
$ _

you will see how the second message is always written by the same shell process, but the process that executes the cd command is different (the subshell that is started to do the cd command)

  •  Tags:  
  • Related