Trying to use dpkg within a folder only on files with the keyword 'mono' in the title - linux

I'm currently trying to install mono using dpkg, and all the other files within the same folder using apt-get, I know I need to use some form of this:
sudo grep 'mono' | dpkg -R --install >/dev/null
however there are too many unknowns for me to complete it and fill in whatever blanks there may be, any help would be greatly appreciated!

Try this:
ls | grep "mono" | sudo xargs dpkg -R --install >/dev/null
The ls will only give files from the current directory. You could also use ls -d *mono* instead of the ls and grep, but I think the ls and grep is easier to understand
The grep is as you had, but now has input from the ls to grep on. You can try ls | grep "mono" to see what files it selects.
Then the sudo is moved to the dpkg part of the script to make dpkg run as root. The way you had it grep runs as root and dpkg as your user
The xargs will take whatever input you had, and put it after the next command. It will take command line length limits in account and execute multiple dpkg commands if the command line gets too big. Note that if your files have spaces in their names, xargs will see the space as start of a new file and you will have problems. There are solutions to that, but really, the easiest solution is to have no files with spaces.
In this example, lets say there are 2 files from the grep "mono1.deb and "mono2.deb" the command executed will be dpkg -R --install mono1.deb mono2.deb. If for some reason you want only one deb per dpkg execution you can change it to ...xargs -n1 dpkg... and it will run dpkg -R --install mono1.deb and also dpkg -R --install mono2.deb
The >/dev/null make sure you won't get any output. Note that you will still get the errors though!

Related

Different behavior between running command with prefix sudo and as root user, seemingly sudo is less authorized [duplicate]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
The community reviewed whether to reopen this question 3 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I've been given sudo access on one of our development RedHat linux boxes, and I seem to find myself quite often needing to redirect output to a location I don't normally have write access to.
The trouble is, this contrived example doesn't work:
sudo ls -hal /root/ > /root/test.out
I just receive the response:
-bash: /root/test.out: Permission denied
How can I get this to work?
Your command does not work because the redirection is performed by your shell which does not have the permission to write to /root/test.out. The redirection of the output is not performed by sudo.
There are multiple solutions:
Run a shell with sudo and give the command to it by using the -c option:
sudo sh -c 'ls -hal /root/ > /root/test.out'
Create a script with your commands and run that script with sudo:
#!/bin/sh
ls -hal /root/ > /root/test.out
Run sudo ls.sh. See Steve Bennett's answer if you don't want to create a temporary file.
Launch a shell with sudo -s then run your commands:
[nobody#so]$ sudo -s
[root#so]# ls -hal /root/ > /root/test.out
[root#so]# ^D
[nobody#so]$
Use sudo tee (if you have to escape a lot when using the -c option):
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
The redirect to /dev/null is needed to stop tee from outputting to the screen. To append instead of overwriting the output file
(>>), use tee -a or tee --append (the last one is specific to GNU coreutils).
Thanks go to Jd, Adam J. Forster and Johnathan for the second, third and fourth solutions.
Someone here has just suggested sudoing tee:
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
This could also be used to redirect any command, to a directory that you do not have access to. It works because the tee program is effectively an "echo to a file" program, and the redirect to /dev/null is to stop it also outputting to the screen to keep it the same as the original contrived example above.
A trick I figured out myself was
sudo ls -hal /root/ | sudo dd of=/root/test.out
The problem is that the command gets run under sudo, but the redirection gets run under your user. This is done by the shell and there is very little you can do about it.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
The usual ways of bypassing this are:
Wrap the commands in a script which you call under sudo.
If the commands and/or log file changes, you can make the
script take these as arguments. For example:
sudo log_script command /log/file.txt
Call a shell and pass the command line as a parameter with -c
This is especially useful for one off compound commands.
For example:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
Arrange a pipe/subshell with required rights (i.e. sudo)
# Read and append to a file
cat ./'file1.txt' | sudo tee -a '/log/file.txt' > '/dev/null';
# Store both stdout and stderr streams in a file
{ command1 arg; command2 arg; } |& sudo tee -a '/log/file.txt' > '/dev/null';
Yet another variation on the theme:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Or of course:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
They have the (tiny) advantage that you don't need to remember any arguments to sudo or sh/bash
Clarifying a bit on why the tee option is preferable
Assuming you have appropriate permission to execute the command that creates the output, if you pipe the output of your command to tee, you only need to elevate tee's privledges with sudo and direct tee to write (or append) to the file in question.
in the example given in the question that would mean:
ls -hal /root/ | sudo tee /root/test.out
for a couple more practical examples:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
In each of these examples you are taking the output of a non-privileged command and writing to a file that is usually only writable by root, which is the origin of your question.
It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo but when the source command is a script that you don't completely trust, it is crucial.
Note you can use the -a option to tee to append append (like >>) to the target file rather than overwrite it (like >).
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
The way I would go about this issue is:
If you need to write/replace the file:
echo "some text" | sudo tee /path/to/file
If you need to append to the file:
echo "some text" | sudo tee -a /path/to/file
Don't mean to beat a dead horse, but there are too many answers here that use tee, which means you have to redirect stdout to /dev/null unless you want to see a copy on the screen.
A simpler solution is to just use cat like this:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo instead of the one running it.
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
I would do it this way:
sudo su -c 'ls -hal /root/ > /root/test.out'
This is based on the answer involving tee. To make things easier I wrote a small script (I call it suwrite) and put it in /usr/local/bin/ with +x permission:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$#" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
sudo tee "$#" > /dev/null
As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo).
echo test | suwrite /root/test.txt
Note that since this is a simple wrapper for tee, it will also accept tee's -a option to append, and also supports writing to multiple files at the same time.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
It also has some simplistic protection against writing to /dev/ devices which was a concern mentioned in one of the comments on this page.
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.

Terminal hangs when executing yum commands

During a patch window, the yum update command stopped running with a Bus Error. Now when I try to execute a yum command my terminal hangs and I need to kill the process.
I have tried to kill all the yum commands running that showed with the ps -aef | grep yum, this did not help.
I have tried to rm -f /var/run/yum.pid and rm -f /var/cache/yum
Afterward, I ran the command rpm --rebuilddb after these commands yum still hangs and I need to kill the process.
No matter what yum command I use it hangs.
Any suggestions?
I had a similar issue (on Redhat 7).
For me, this worked out:
sudo kill -9 $(ps aux | grep -E 'yum|rpm' | awk '{print $2}')
sudo rm -rf /var/lib/rpm/__db* /var/lib/rpm/.dbenv.lock
sudo rpm --rebuilddb
Be careful though, 'kill -9' is a bad way to stop processes. Especially recursive like the above.
Use the above as a last effort to overcome you issue, after you have examinated your processes running.

How to read a file using cat with Perl -e parameters?

I've set up a penetration testing VM and am trying to practice privilege escalation.
I'm currently trying to read a file. I do not have access to the user's home directory where the file is located but I have permissions to run /usr/bin/perl as the user/admin.
My understanding is that I could run the following command to essentially cat the file and see what's inside using the perl permissions granted to me but it doesn't seem to be working and gives no result back
james#linuxtest:~$ sudo -l
Matching Defaults entries for james on linuxtest:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User james may run the following commands on linuxtest:
(james2) /usr/bin/perl
james#linuxtest:~$ sudo -u james2 perl -e 'print 'cat /home/james/test.txt''
I expected the result to be the contents of the file or at least an error of some sort but no result. Am I making a stupid mistake here?
I think you wanted
sudo -u james2 perl -e 'print `cat /home/james/test.txt`'
Backticks are used to execute a shell command and capture its output.
That's a weird way of doing
sudo -u james2 perl -e 'system "cat /home/james/test.txt"'
which is a weird way of doing
sudo -u james2 cat /home/james/test.txt
And since you're root, that's a weird way of doing
cat /home/james/test.txt

append text string from file to a command

How to put a text string from file to the end of a command?
What I want to is to use sudo dpkg -i with | or < or > (or whatever else) to input the strin from file in which would be the package names. To demonstrate it:
$ ls
file pkg1.deb pkg2.deb pkg3.deb pkg4.deb
$ more file
pkg1.deb pkg3.deb
$ sudo dpkg -i < file
and the installation of the selected packages should run.
Info: I am using Ubuntu 13.10 i386
$ sudo dpkg -i $(<file)
ought to work, assuming that dpkg -i can take multiple package names (don't have a debian box around to check). If not:
for X in $(<file) ; do sudo dpkg -i "$X" ; done

How do I use sudo to redirect output to a location I don't have permission to write to? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I've been given sudo access on one of our development RedHat linux boxes, and I seem to find myself quite often needing to redirect output to a location I don't normally have write access to.
The trouble is, this contrived example doesn't work:
sudo ls -hal /root/ > /root/test.out
I just receive the response:
-bash: /root/test.out: Permission denied
How can I get this to work?
Your command does not work because the redirection is performed by your shell which does not have the permission to write to /root/test.out. The redirection of the output is not performed by sudo.
There are multiple solutions:
Run a shell with sudo and give the command to it by using the -c option:
sudo sh -c 'ls -hal /root/ > /root/test.out'
Create a script with your commands and run that script with sudo:
#!/bin/sh
ls -hal /root/ > /root/test.out
Run sudo ls.sh. See Steve Bennett's answer if you don't want to create a temporary file.
Launch a shell with sudo -s then run your commands:
[nobody#so]$ sudo -s
[root#so]# ls -hal /root/ > /root/test.out
[root#so]# ^D
[nobody#so]$
Use sudo tee (if you have to escape a lot when using the -c option):
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
The redirect to /dev/null is needed to stop tee from outputting to the screen. To append instead of overwriting the output file
(>>), use tee -a or tee --append (the last one is specific to GNU coreutils).
Thanks go to Jd, Adam J. Forster and Johnathan for the second, third and fourth solutions.
Someone here has just suggested sudoing tee:
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
This could also be used to redirect any command, to a directory that you do not have access to. It works because the tee program is effectively an "echo to a file" program, and the redirect to /dev/null is to stop it also outputting to the screen to keep it the same as the original contrived example above.
A trick I figured out myself was
sudo ls -hal /root/ | sudo dd of=/root/test.out
The problem is that the command gets run under sudo, but the redirection gets run under your user. This is done by the shell and there is very little you can do about it.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
The usual ways of bypassing this are:
Wrap the commands in a script which you call under sudo.
If the commands and/or log file changes, you can make the
script take these as arguments. For example:
sudo log_script command /log/file.txt
Call a shell and pass the command line as a parameter with -c
This is especially useful for one off compound commands.
For example:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
Arrange a pipe/subshell with required rights (i.e. sudo)
# Read and append to a file
cat ./'file1.txt' | sudo tee -a '/log/file.txt' > '/dev/null';
# Store both stdout and stderr streams in a file
{ command1 arg; command2 arg; } |& sudo tee -a '/log/file.txt' > '/dev/null';
Yet another variation on the theme:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Or of course:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
They have the (tiny) advantage that you don't need to remember any arguments to sudo or sh/bash
Clarifying a bit on why the tee option is preferable
Assuming you have appropriate permission to execute the command that creates the output, if you pipe the output of your command to tee, you only need to elevate tee's privledges with sudo and direct tee to write (or append) to the file in question.
in the example given in the question that would mean:
ls -hal /root/ | sudo tee /root/test.out
for a couple more practical examples:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
In each of these examples you are taking the output of a non-privileged command and writing to a file that is usually only writable by root, which is the origin of your question.
It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo but when the source command is a script that you don't completely trust, it is crucial.
Note you can use the -a option to tee to append append (like >>) to the target file rather than overwrite it (like >).
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
The way I would go about this issue is:
If you need to write/replace the file:
echo "some text" | sudo tee /path/to/file
If you need to append to the file:
echo "some text" | sudo tee -a /path/to/file
Don't mean to beat a dead horse, but there are too many answers here that use tee, which means you have to redirect stdout to /dev/null unless you want to see a copy on the screen.
A simpler solution is to just use cat like this:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo instead of the one running it.
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
I would do it this way:
sudo su -c 'ls -hal /root/ > /root/test.out'
This is based on the answer involving tee. To make things easier I wrote a small script (I call it suwrite) and put it in /usr/local/bin/ with +x permission:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$#" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
sudo tee "$#" > /dev/null
As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo).
echo test | suwrite /root/test.txt
Note that since this is a simple wrapper for tee, it will also accept tee's -a option to append, and also supports writing to multiple files at the same time.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
It also has some simplistic protection against writing to /dev/ devices which was a concern mentioned in one of the comments on this page.
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.

Resources