What does the -b argument do in csh? - linux

I am looking at a tcsh script that has the following shebang line:
#!/bin/tcsh -fb
# then executes some commands
What does the -b do?
From the man page:
-b Forces a ''break'' from option processing, causing any further shell arguments to
be treated as non-option arguments. The remaining arguments will not be inter-
preted as shell options. This may be used to pass options to a shell script with-
out confusion or possible subterfuge. The shell will not run a set-user ID script
without this option.
But I don't really understand what it means...
An example would be great.
Thanks.

Say, for example, you have a script that is named --help and you want to execute it using tcsh:
tcsh --help
This will obviously not work. The -b forces tcsh to stop looking for arguments and treat the rest of the command line as file names or arguments to scripts. So, to run the above weirdly named script, you could do
tcsh -b --help

Related

Bash - How to execute a script which is output from a different script

I have a CLI which generates a bash script. How can I evaluate it immediatly without redirecting to a .sh file?
example is to change the following:
~: toolWhichGeneratesScript > tmp.sh
~: chmod +x tmp.sh
~: ./tmp.sh
to something like:
~: toolWhichGeneratesScript | evaluate
You can pass in commands to run with bash -c (or sh -c):
bash -c "$(toolWhichGeneratesScript)"
-c If the -c option is present, then commands
are read from the first non-option argument
command_string. If there are arguments
after the command_string, they are assigned
to the positional parameters, starting with
$0.
Unlike piping to the shell, this leaves stdin free for you to interact with prompts and programs the script runs.
The shell reads its script from standard input:
toolWhichGeneratesScript | sh
(In fact, an interactive shell does the same; it's standard input just happens to be a terminal.)
Note that you need to know which shell to use; if your tool outputs bash extensions, then you have to pipe it to bash. Also, if the generated script itself needs to read from standard input, you have a bit of a problem.
Try to do this : toolWhichGeneratesScript | bash

Wrong BASH-Variable return from a bash script

I'd like to check the value of $HISTFILE (or any similar BASH-Variable) by a bash script. On the command console 'echo $HISTFILE' is the way I normally go, but from inside a bash script, which only includes:
#!/bin/bash
echo $HISTFILE
gives an empty line instead of showing $HOME/$USER/.bash_history (or similar return values). My questions are:
What is the reason for doing so (since I never had such trouble using bash scripts) and
how can I check the value of BASH-Variables like $HISTFILE from inside a bash script?
Many thanks in advance. Cheers, M.
HISTFILE is only set in interactive shells; scripts run in non-interactive shells. Compare
$ bash -c 'echo $HISTFILE' # non-interactive, no output
$ bash -ic 'echo $HISTFILE' # interactive, produces output
/home/me/.bash_history
However, forcing the script to run in an interactive shell will also cause your .bashrc file to be sourced, which may or may not be desirable.

What is the difference between `./example.sh` and `sh example.sh`

I am trying to play with bash and arrays. But executing a sample script, I got an unexpected syntax error message: example.sh: 3: example.sh: Syntax error: "(" unexpected. And this is the script
#!/bin/bash
array=( one two three )
If I run the script with ./example.sh it works and no errors are displayed. But if I run sh example.sh I get the error message.
I thought that these two commands are the same:
sh example.sh
./example.sh
so ... what is the difference between the two?
When you launch it via ./example.sh then the command specified in the first line of the script is used to interpret the content. So your script executes in a bash, where such syntax is allowed for arrays.
When you launch it via sh example.sh then sh is the command that is used to interpret the content of the file. sh is the original Unix shell (aka Bourne shell) and this shell is a little more rude than bash (Bourne again shell). You don't have such arrays. Note that in sh the first line of your script is just interpreted as a comment.
by using sh example.sh
- you are specifying what shell interpreter to use for that script. Example being "bash example.sh" instead of "sh example.sh" etc etc.
Running scripts this way disregards the "shebang (#!/bin/bash)" that you have specified inside of the script. Since you wrote a bash script but are trying to run it as just "sh", this is why it is failing
by using ./example.sh,
- You are specifying to run the script from your current directory. This will attempt to run the script in whatever shell you are currently in unless a shebang is specified. Since you have a "shebang" specified to run the script in bash... this is why it is working.
array_name=(value1 ... valuen)
This is how to initializes an array in bash only. When you execute ./example.sh, the shebang line #!/bin/bash tells the system to use bash to execute.
However, when you execute sh example.sh, sh is used to execute. In many Unix systems (like Linux), sh is equivalent to bash. It seems sh is a different shell on your system.

How to check differences in bash and other shell profiles

I have some shell scripts which I run in my Linux/AIX machine with bash profile. Now my bash profile is going to be remove, and I will have Korn shell (ksh) or the C shell (csh). How to verify whether my scripts will run fine in Korn shell (ksh) or C shell (csh), even after bash shell is removed. Also, is there any differnce in commonly used commands between bash and other (ksh, csh). Is there command to check, which shell is getting used while running the shell script.
First of all, this is not a problem, the default shell of your account is irrelevant. As long as bash is installed on the machine, you can use it to run your code. Either add a shebang line as the first line of your script:
#!/usr/bin/env bash
Or, explicitly run the script with bash:
$ /bin/bash /path/to/script.sh
As for the differences, yes there are many. A script written for bash will not run in csh, their syntax is completely different. It might run on ksh but that will depend on your script. Not all features of the two shells are the same. For example:
$ cat test.sh
var="foo";
echo $var;
$ bash ./test.sh
foo
$ ksh ./test.sh
foo
$ csh ./test.sh
var=foo: Command not found.
var: Undefined variable.
As you can see above, var=foo runs correctly in ksh (which is part of the bourne shell family) but fails for csh. Basically, think of each shell as its own programming language. You wouldn't expect the python interpreter to be able to run a perl program, why do you expect one shell to be able to run a script written for another?
OP writes bash is going to be removed.
If you really cannot get bash installed. start each script with #!/bin/ksh and check for syntax problems:
ksh -n migrated_script
When you use bash/linux specific things you need to address them:
AIX will be "missing" flags on commands like find (changed last hour...) and ksh itself is also different.
Do not try csh, that is completely different.

Linux shell script syntax error on exec command

I added the following command near the top of my shell script in order to record the script output to a file. This works with no problem when I run the script as my user, jsmith, however when the script is run as root in a crontab, I receive an error:
syntax error near unexpected token:
exec &> >(tee $LOG_PATH$TIMESTAMP.log)
I do have both $LOG_PATH and $TIMESTAMP correctly defined above the command as:
LOG_PATH="/home/jsmith/script/logs/"
TIMESTAMP="$(date -d "today" +"%Y-%m-%d-%H:%M")"
Any ideas? Thanks!
Usually, Linux feature multiple shells (sh, csh, dash, bash, etc.) which have subtle syntax differences. It is possible that you tested your script with bash, whereas crontabs are executed with dash.
I suggest you the following:
check what shell your script requires (looks at the first line)
tell cron to use that shell, i.e., set SHELL=/bin/my_shell at the beginning of your crontab (see the manpage for details).

Resources