Linux: Illegal Option Read -A

How can I resolve this error in shell scipting: read: Illegal option -s?

Just as descripted by this question , I solved this error by using #!/bin/bash instead of #!/bin/sh.It really worked !

git alias now fails saying read: illegal option -t

My previous laptop ran Fedora 33 where sh points to Bash. Whereas on the new laptop running Ubuntu, sh points to Dash as pointed out by @KamilCuk in a comment.

Now, there is no way to configure git to use a specific shell for aliases.

How can I resolve this error in shell scripting: read: Illegal option -t?

Bash supports -t, so it looks like you're trying to execute it with sh or some other shell, which is odd, since you have the correct shebang.

Make sure you run it with ./script or path_to_script/script. If you just run it in the terminal, first start bash.

read: Illegal option -d

If you run sh and then try that command, you get:

read: 1: Illegal option -d

If you do it while still in bash, it works fine.

I therefore deduce that your script is not running under bash.

Make sure that your script begins with the line:

#!/usr/bin/env bash

(or equivalent) so that the correct shell is running the script.

Alternatively, if you cannot do that (because the script is not a bash one), just be aware that -d is a bash feature and may not be available in other shells. In that case, you will need to find another way.

How do i resolve the error read: Illegal option -d . i wish to run it under sh. is there any alternative route

If you want to reliably/portably run a script with /bin/sh, you can only use features that the POSIX sh specification guarantees -- which for read means those features documented at https://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html. read -d is not one of those features.

However, there's an alternate way to get arbitrary filenames out of find into your shell; you can pass them on the command line with -exec instead of streaming them NUL-delimited with -print0:

find . -type f -exec sh -c '
for file do
fmt=$(stat -c "%Y : %n" "$file")
if ! grep -Fxq "$fmt" log.txt; then
printf "%s\n" "$fmt" >>new_files_log.txt
fi
printf "%s\n" "$fmt" >>log.txt
done
' _ {} +

That said, note that this code (running grep over and over, once per line) is extremely inefficient, and I wouldn't ever recommend using it for anything. Much more efficient to generate all your output unconditionally, sort it all in one batch, and use comm to efficiently merge new and preexisting streams; see BashFAQ #36.


A more efficient solution (to maintain a new-log.txt showing files that recently were created, and a last-log.txt with all files that existed as of the immediately prior run) might look like:

touch last-log.txt # create if not already present
find . -type f -exec stat -c '%Y : %n' -- {} + | sort >current-log.txt
comm -13 last-log.txt current-log.txt >new-log.txt
mv current-log.txt last-log.txt

Note that this requires last-log.txt to be sorted; if you're using a preinitialized file, be sure you maintain that constraint.

Bash autocompletion in user input, Makefile

make uses /bin/sh as default shell and on many systems it's not the same as bash (e.g. on Debian is dash). I suspect that the -e option of read is a bash extension, that is why you get the error:

/bin/sh: 1: read: Illegal option -e

setting /bin/bash as the SHELL in the Makefile should work:

Makefile

SHELL := /bin/bash

initProjectLaTeX:
@read -e -p "Enter destination: " destination; \
mkdir -pv $$destination; \
cp -iv ~/tmp/*c $$destination

example

$ make initProjectLaTeX
Enter destination: foo/bar/baz
mkdir: created directory 'foo'
mkdir: created directory 'foo/bar'
mkdir: created directory 'foo/bar/baz'
'/home/marco/tmp/foo.c' -> 'foo/bar/baz/foo.c'
$ tree foo
foo
└── bar
└── baz
└── foo.c

2 directories, 1 file
$

completion

$ make initProjectLaTeX
Enter destination: foo
foo/ foo.c
Enter destination: foo
foo/ foo.c
Enter destination: foo


Related Topics



Leave a reply



Submit