-2

Is there any way to manipulate terminal input before it gets executed? Example:

apt-get update is entered in the terminal. Now I want to change it to sudo apt-get update before it gets executed.

What I tried:

I thought about a possibility to execute a script which would then execute the entered command with the manipulated Input, but I didn't find a way to run that script while another program should be executed.

I appreciate every answer. I'm on Linux Mint Serena.

Clarification:

Whenever a command is invoked there should be a script or whatsoever running in the background and check if it matches a pattern. If no then execute input and if yes then manipulate that command and execute -> That's why my example with apt-get update to sudo apt-get update. The only thing I can` figure out is, how that script would get that command before it would be executed.

Possible purposes:

  • When trying to access a specific file/directory do a password prompt

  • Creating shortcuts (cd _1 will be changed to cd ~/Desktop)

  • heard of cron? screen? & bg fg? – mahatmanich Jul 28 '17 at 9:45
  • Yes but how should I use that to solve that kind of problem? @mahatmanich – ADDB Jul 28 '17 at 9:46
  • you can run a script like so sh script.sh & and it will be put in the background of the shell. With the command jobs you can view all running jobs in the background bg. – mahatmanich Jul 28 '17 at 9:46
  • So like a script that'll be run on start which is in the background. Then using read to get the input and then manipulate it using the script? @mahatmanich – ADDB Jul 28 '17 at 9:48
  • Your question is very vague ... who enters what into your terminal? why don't you enter sudo apt-get update all along? – mahatmanich Jul 28 '17 at 9:48
1

UH, something completely new (to me): read the answer to use PS4: how to intercept every command

If just tested:

bash: PS4='$(echo $(date) $(history 1) >> /tmp/trace.txt) TRACE: '
bash: set -x
bash: date
 TRACE: date
Fr 28. Jul 14:13:24 CEST 2017

As described in the answer above, PS4 ... is evaluated for every command being executed .... So if you substitute this to pass any of your commands through your wrapper and validate for execution, this way you can intercept any of your commands.

  • 1
    setting PS4 doesn't allow modification of the command before it's executed. it only allows changing the output of sh execution tracing. – cas Jul 29 '17 at 1:14
2

In zsh, you could add some checkers that do:

validate_apt-get_update() {
  local match MATCH MBEGIN MEND mbegin mend
  if [[ $BUFFER =~ '^(\s*)(apt-get\s+update.*)' ]]; then
    LBUFFER="$match[1]sudo " RBUFFER=$match[2]
    zle -M 'WARNING: sudo has been added before apt-get update'
    return 1
  fi
}

accept-line() {
  validate_apt-get_update && zle .accept-line
}

zle -N accept-line

Which would insert sudo, position the cursor just after it, give you a warning message and not accept the line if you entered a line whose first 2 words were apt-get and update, giving you an opportunity to check that it's really what you want.

Here, we're doing our own simplified parsing of the shell command line. It would not work if you entered:

'apt-get' update
"$(echo apt-get)" update
something else; apt-get update...

Which may be just as well, because that allows you do do:

\apt-get update

If you want to bypass that check like when you want to bypass aliases.

For your cd _1 that becomes cd ~/Desktop, you can do:

set -o cdable_vars
_1=~/Desktop

Personally, I don't like much the idea of the shells doing things (especially things that others at least would not expect) behind my back like that.

1

Depending o your shell, you can create an alias (wikipedia has details of the concept).

To create a permanent alias in bash, you'd add it to your .bashrc, which you can edit like this: gedit ~/.bashrc

You'd then simply add a line at the bottom like:

alias apt-get-update='sudo apt-get update'

Notice that creating aliases with multiple words won’t work unless you connect them with a dash or underscore.

  • Would it be possible to set an alias for e.g. cd *='...', so that every cd command would be aliased? – ADDB Jul 28 '17 at 10:06
  • 1
    No, but please describe your usecase so we can help you better. – Jan Jul 28 '17 at 10:06
  • Okay I'll try to clarify it. Whenever a command is invoked there should be a script or whatsoever running in the background and check if it matches a pattern. If no then execute input and if yes then manipulate that command and execute -> That's why my example with apt-get update to sudo apt-get update. The only thing I can` figure out is, how that script would get that command before it would be executed. – ADDB Jul 28 '17 at 10:13
  • What's the ultimate goal? Security? – Jan Jul 28 '17 at 10:15
  • It would have multiple purposes. Like when entering specific directories ask for a password (-> security), shortcuts (cd _1 would switch to desktop directory) and so on – ADDB Jul 28 '17 at 10:20
1

If it is only for your login you may write a wrapper script that is executed before your system command. To get your wrapper be executed before system command, you have to modify your PATH variable.

For example:

  1. Create an path for your wrapper:

    mkdir $HOME/wrapper
    
  2. Prepend your wrapper path to PATH (for example inside $HOME/.bashrc):

    export PATH="/home/myuser/wrapper:$PATH`
    
  3. Sample script $HOME/wrapper/ls:

    #!/bin/bash
    echo "sudo ls $*"
    

Now the execution looks like so:

stackoverflow: ls /home
sudo ls /home

For security reasons, pay attention that no one else can modify your wrapper script so not execute a hacker script with sudo privileges. There are several reasons to not modify your PATH variable like that.

If you do this system-wide (modify /etc/profile for PATH and place wrapper for example inside /usr/wrapper) it is very important to pay attention that no one may place their own files inside!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.