Make shell command from child process execute in parent (to lock shell) - linux

I have a user defined command called lock. After executing the command, the system will be locked. If we give only the correct password, then only the command
prompt occurs. Now, I want to execute the lock command from the script which is
running in background. If we execute the script lock command is executed, But it does not lock the current terminal. It locks only the background bash. It does not executed in current bash. How to solve this problem?
Thanks.

You can execute a command before a command is executed from the command prompt using the DEBUG trap:
trap 'command' DEBUG
This will execute command before each command. Change you background script to create a flag file of some kind when the system is locked. And make your command check if that file exists. Like this:
if [[ -f lockfile ]]
then p=
while [[ "$p" != secret ]]
do echo -n password:
read p
done
rm -f lockfile
fi
I am not saying it is secure.
Another method:
Run two shells. The lower shell loops asking for a password and then runs the upper. The upper shell is a normal shell. The background task kills the upper shell when it wants to lock the terminal, returning control to the lower shell.

Related

linux "enable -n xxx" command works in terminal but not when put into a script

I've found a very strange issue, when in linux terminal I type "enable -n trap", it would disable the trap linux builtin command. But if I put it into a script like
#!/bin/bash
enable -n trap
and then run the script, there's no error but the command is also not disabled. Really appreciate if someone could share what is happening and how to run it in some file instead of directly in the terminal. Thank you!
The enable command only affects the current shell. When you run a script, that script is executed in a new process, so:
A new shell starts
The enable command runs and disables the trap command in that shell
The shell exits
If you want to affect the current shell, your only option is to source the script using the . (or source) command. If the script is named disable-trap.sh and is in your $PATH, you can run:
. disable-trap.sh
You can also provide a full path to the script:
. /path/to/disable-trap.sh
Sourcing a script like this is largely equivalent to typing the same commands in at the command line: it executes the instructions in the script in the current shell, rather than spawning a new process.

What is the purpose of using exec command

Here I don't understand what the following piece of code is trying to achieve, I did search
online for the use of exec but don't quite get the idea, could anyone please help to explain?
Code snippet:
exec $(dirname "$0")/init.sh -l interface.mod -l instrument.mod -a postinit.mod -a async.mod "$#"
Thanks.
The exec is a builtin command of the Bash shell which allows you to execute a command that completely replaces the current process, i.e., the current shell process is destroyed, and entirely replaced by the command you specify. It is useful when you want to run a command, but you don't want a bash shell to be the parent process. When you exec a command, it replaces bash entirely - no new process is forked, no new PID is created, and all memory controlled by bash is destroyed and overwritten. This can be useful if, for instance, you want to give a user restricted access to a certain command. If the command exits because of an error, the user will not be returned to the privileged shell that executed it. exec may also be used without any command, to redirect all output of the current shell to a file. Here is the definition from man bash:
exec [-cl] [-a name] [command [arguments]]
If command is specified, it replaces the shell. No new process
is created. The arguments become the arguments to command. 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. The -c option causes command to be executed
with an empty environment. If -a is supplied, the shell passes
name as the zeroth argument to the executed command. If command
cannot be executed for some reason, a non-interactive shell
exits, unless the exec fail shell option is enabled. In that
case, it returns failure. An interactive shell returns failure
if the file cannot be executed. If command is not specified,
any redirections take effect in the current shell, and the
return status is 0. If there is a redirection error, the return
status is 1.

How to make shell execute a command prior to every user input command

I need a command to be executed before shell starts to execute the user passed command,i tried using trap with DEBUG signal, but that did not happen.
I have registered trap in /etc/profile.
trap 'echo "my_command"' DEBUG
Whats happening now is:
sw0:root:root> pwd
/root
my_command
sw0:root:root>
What i want is:
sw0:root:root> pwd
my_command
/root
sw0:root:root>
Bash Version Used:
GNU bash, version 2.04.0(1)-release (powerpc-unknown-linux-gnu)
I want my command to be executed prior to every command entered by user in shell,how do i do that?
Please help me on this,i tried lot of googling but that does not help.
You are probably looking for something like PROMPT_COMMAND:
The contents of this variable are executed as a regular Bash command just before Bash displays a prompt.
My example
function preexec() {
echo "Preexec command"
}
trap 'preexec' DEBUG
Result is
# pwd
Preexec command
/home/robert

Using konsole to emulate a terminal through Perl

I have an issue when using this command
system("konsole --new-tab --workdir<dir here> -e perlprogram.pl &");
It opens perlprogram.pl which has:
system("mpg321 song.mp3");
I want to do this because mpg321 stalls the main perl script. so i thought by opening it in another terminal window it would be ok. But when I do run the first script all it does is open a new tab and do nothing.
Am I using konsole correctly?
Am I using konsole correctly?
Likely, no. But that depends. This question can be decomposed into two issues:
How do I achieve concurrency, so that my program doesn't halt while I execute an external command
How do I use konsole.
1. Concurrency
There are multiple ways to do that. Starting with the fork||exec('new-program'), to system 'new-program &', or even open.
system will invoke the standard shell of your OS, and execute the command you provided. If you provide multiple arguments, no shell escaping is done, and the specified program execed directly. (The exec function has the same interface so far). system returns a number that specifies if the command ran correctly:
system("my-command", "arg1") == 0
or die "failed my-command: $?";
See perlfunc -f system for the full info on what this return value signifies…
The exec never returns if successfull, but morphs your process into executing the new program.
fork splits your process in two, and executes the child and the process as equal copies. They only differ in the return value of fork: The parent gets the PID of the child; the child gets zero. So the following executes a command asynchronously, and lets your main script execute without further delay.
my #command = ("mpg321", "song.mp3");
fork or do {
# here we are in the child
local $SIG{CHLD} = 'IGNORE'; # don't pester us with zombies
# set up environment, especially: silence the child. Skip if program is well-behaved.
open STDIN, "<", "/dev/null" or die "Can't redirect STDIN";
open STDOUT, ">", "/dev/null" or die "Can't redirect STDOUT";
exec {$command[0]} #command;
# won't ever be executed on success
die qq[Couldn't execute "#command"];
};
The above process effectively daemonizes the child (runs without a tty).
2. konsole
The command line interface of that program is awful, and it produces errors half the time when I run it with any parameters.
However, your command (plus a working directory) should actually work. The trailing ampersand isn't neccessary, as the konsole command returns immediately. Something like
# because I `say` hello, I can be certain that this actually does something.
konsole --workdir ~/wherever/ --new-tab -e perl -E 'say "hello"; <>'
works fine for me (opens a new tab, displays "hello", and closes when I hit enter). The final readline there keeps the tab open until I close it. You can keep the tab open until after the execution of the -e command via --hold. This allows you to see any error messages that would vanish otherwise.

How to stop a zsh script from being suspended (tty output)

I have a zsh script that I want to run such that it also loads up my .zshrc file.
I believe I have to run my script in interactive mode?
Thus, my script begins like:
#!/bin/zsh -i
if [ $# = 0 ]
then
echo "need command line paramter..."
exit
fi
However, when I try to run this script in the background, my script becomes suspended (even if I pass in the correct number of parameters):
[1] + suspended (tty output)
My question is: How can I make a script that can run in the background that also loads my startup .zshrc file? If I have to put it into interactive mode, how can I avoid the suspension on tty output problem?
Thanks
Don't use interactive mode as a hash-bang!
Instead, source your zshrc file in the script if you want it:
#!/bin/zsh
source ~/.zshrc
...
For future reference, you can use the disown bultin to detach a previously backgrounded job from the shell so it can't be suspended or anything else. The parent shell can then be closed with no affect on the process:
$ disown %1
You can do this directly from the command line when you start the program by using the &! operator instead of just &:
$ ./my_command &!

Resources