0

I'm a greenhorn at bash scripting. I have a file called dir.txt storing this text:

./src/defaultPackage

how do I read dir.txt and switch to directory ./src/defaultPackage in one line?

I've tried cat ./dir.txt | xargs cd but cd throws no such file or directory error

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Erik K
  • 11
  • 1
  • Btw.: If bash's `autocd` feature is available and enabled (`shopt -s autocd`) then `$(head -1 dir.txt)` is sufficient. This feature is only used by interactive shells. – Cyrus Jun 11 '20 at 05:15
  • Duplicate of [How do I use the lines of a file as arguments of a command?](https://stackoverflow.com/questions/4227994/how-do-i-use-the-lines-of-a-file-as-arguments-of-a-command). [What am I doing wrong in this bash function?](https://stackoverflow.com/questions/3763217/what-am-i-doing-wrong-in-this-bash-function) is also related although the title is really vague. – oguz ismail Jun 11 '20 at 06:19
  • 1
    `xargs cd` will not be useful in any context, because `xargs` is for running external commands and `cd` is a shell builtin. It is not `cd` throwing `no such file or directory`, but `xargs` throwing that error, because it cannot find any command called `cd`. – alani Jun 11 '20 at 07:37

2 Answers2

4

You could do

 cd "$(head -1 dir.txt)"

for explanations, read the GNU bash manual then head(1). In some cases (e.g. if dir.txt contains comments) you may want to use gawk(1) instead of head.

Notice that xargs(1) cannot work with any bash-builtins(7), including cd; xargs needs an executable file (or script) since it uses exec(3) functions. See execve(2) and elf(5).

You may want to read Advanced Linux Programming and syscalls(2) then study the source code of your GNU bash, which is free software. You could be interested in using strace(1) or ltrace(1) or gdb(1) to understand the behavior of programs or processes, including your Unix shell.

Of course, avoid weird characters such as newlines, tabs, or spaces in file or directory names. See path_resolution(7) and glob(7).

You could consider using GNU guile (see this and SICP) or Python for your scripts. Both are much more readable (and in my opinion, easier to write) than bash or even zsh or fish. Of course, use a distributed version control system (such as git or mercurial) on your scripts.

You might be interested by Linux From Scratch.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

Using only builtins:

IFS= read -r line < dir.txt
cd -- "$line"

To read a line from a file, use read (and not head/cat/sed/whatever).

The reason you get your error, is that cd is a builtin, and not a command in your PATH: it wouldn't make sense for cd to be an external command, and it changes the internal state of the shell.

Note that if the line is empty, this will cd to $HOME. To avoid that:

IFS= read -r line < dir.txt && cd -- "${line:-.}"
gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104