Using linux script command - linux

The script command executes and records logs.
( http://www.computerhope.com/unix/uscript.htm )
( http://linuxers.org/article/script-command-line-tool-recordsave-your-terminal-activity )
I use script command for saving commands and those output.
Whenever using 'script', I type commands like followings.
$ script result.log
Script started, file is result.log
$ date
$ ls -la.
$ exit
Sometimes I want to use those command with shell script.
So I run like following.
$ script -c test.sh result.log
But the result.log has only output, it doesn't contain command itself.
I want the result.log to include commands and output.
How can I do it?
Thanks

if you use sh -x to run your script it will print the commands or add
set -x to your script.
script -c "sh -x ./test.sh" reult.log
sample output:
+ date
Tue Dec 23 09:52:22 CET 2014
+ ls -la

set -o verbose
Execute this on terminal before executing your script or add this at the beginning of the script.
This will change the terminal configuration to echo all the commands before executing them.
This will add the command then followed by the output of that command.
you can also use :
set -x or set -v set -xv
-x option enables variable expansion and echo's all the option used with the command.
-v is similar to -o verbose this simply echo's the command name
-xv echo's both.

Related

Bash command option clarification bash -ex

could you please explain to me what exactly this shell command do?
It is quite difficoult to retrive the description of this -ex option.
sh #!/bin/bash -ex
Thanks in advance
It means you're invoking new bash shell with -e and -x shell options
See shell options here: https://tldp.org/LDP/abs/html/options.html
-e errexit Abort script at first error, when a command exits with non-zero status (except in until or while loops, if-tests, list constructs)
-x xtrace Similar to -v, but expands commands
since -x is similar to -v:
-v verbose Print each command to stdout before executing it
So it's actually dropping to next level shell:
$ echo $SHLVL
1
$ sh #!/bin/bash -ex
$ echo $SHLVL
2
in which in this level 2 shell, option -e and -x is activated

What kind of command is "sudo", "su", or "torify"

I know what they do. I was just wondering what kind of command are they. How can you make one using shell scripting.
For example, command like:
ignoreError ls /Home/
ignoreError mkdir /Home/
ignoreError cat
ignoreError randomcommand
Hope you get the idea
The way to do it in a shell script is with the "$#" construct.
"$#" expands to a quoted list of all of the arguments you passed to your shell script. $1 would be the command you want your shell script to run, and $2 $3 etc are the arguments to that command.
The only example I have is from cygwin. Cygwin does not have sudo, but I have this script that emulates it:
#!/usr/bin/bash
cygstart --action=runas "$#"
So when I run a command like
$ sudo ls -l
my sudo script does whatever it needs to do (cygstart --action=runas) and calls the ls command with the -l argument.
Try this script:
#!/bin/sh
"$#"
Call it, for example, run, make it runnable chmod u+x run, and try it:
$ run ls -l #or ./run ls -l
...
output of ls
...
The idea is that the script takes the parameters specified on the command line and use them as a (sub)command... Modify the script this way:
#!/bin/sh
echo "Trying to run $*"
"$#"
and you will see.

Option -l of exec shell command

Could you please clarify on the use of -l option of exec shell command. I didn't notice any difference when I ran exec ls | cat and exec -l ls | cat.
The -l option of exec adds a - at the beginning of the name of your command. For example:
exec -l diff | head
-diff: missing operand after '-diff'
-diff: Try '-diff --help' for more information.
Note the - everywhere before diff.
The point of all this? If you have a - before a command to start a shell it will act as a login shell. From man bash:
A login shell is one whose first character of argument zero is a -, or one started with the --login option.
Now, man exec states that:
If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is
what login(1) does.
So exec -l bash will run bash as a login shell. To test this, we can use the fact that a login bash executes the file ~/.bash_profile, so:
$ cat ~/.bash_profile
#!/bin/sh
printf "I am a login shell!\n"
If I start a login bash, the command printf "I am a login shell!\n" will be executed. Now to test with exec:
$ exec bash
$
Nothing is displayed, we are on a non-login shell.
$ exec -l bash
I am a login shell!
$
Here we have a login shell.

sudo command behaviour with quotes

I need your help in understanding this behaviour of sudo.
sudo -s -- 'ls -l' this command works but sudo 'ls -l' throws error saying
sudo: ls -l: command not found I realize it treats the entire string within quote as single command (including the spaces) but what I don't get is how does it work fine with -s flag but fails when -s is not there.
Without -s, the first argument is the name of the command to execute. With -s, the first argument is a string passed to the -c option of whatever shell ($SHELL or your system shell) is used to execute the argument.
That is, assuming $SHELL is sh, the following are equivalent:
sudo -s -- 'ls -l'
sudo -- sh -c 'ls -l'
From the sudo man page:
-s [command]
The -s (shell) option runs the shell specified by the SHELL environment variable if it is set or the shell as specified in
the password database. If a command is specified, it is passed to the
shell for execution via the shell's -c option. If no command is
specified, an interactive shell is executed.
It behaves like it does because a new shell is spawned which breaks up the words in your "quoted command" like shells do.

Why does "/usr/bin/env bash -x" only work in command line?

I am playing with a docker CentOS image, and find executing "/usr/bin/env bash -x" command is OK in terminal:
bash-4.1# /usr/bin/env bash -x
bash-4.1# exit
+ exit
exit
But after writing this command into a script and execute it, it doesn't work, and prompts "No such file or directory":
bash-4.1# ls -lt a.sh
-rwxr-xr-x. 1 root root 23 May 20 04:27 a.sh
bash-4.1# cat a.sh
#!/usr/bin/env bash -x
bash-4.1# ./a.sh
/usr/bin/env: bash -x: No such file or directory
Is there any difference between two methods?
The short answer is that you only get one parameter to the interpreter which is specified via the "#!" mechanism. That became "bash -x".
Usually the limitation is more apparent, e.g., using
#!/bin/bash -x -i
would pass "-x -i" as the parameter, and get unexpected results.
Sven Mascheck comments on this in his page on the topic:
most systems deliver all arguments as a single string
The shebang line should have at most one argument.
When you give more arguments, they will not be split. You can compare this with the commandline command
bash-4.1# /usr/bin/env "bash -x"

Resources