Pipes with Apt Package Manager - linux

I have two files, the first one called packages.txt which is list of packages:
gcc
emacs
vim
python
...
Now, when I run the command
cat packages.txt | tr '\n' ' ' | apt-get install
This basically converts the file into one line of packages separated by space. It does not install all the packages in packages.txt. (I think it only installs the first one) Does anyone knows why?

Try using xargs:
xargs -d '\n' -- apt-get install < packages.txt
Or
xargs -d '\n' -n 1 -- apt-get install < packages.txt
Make sure packages.txt is not in DOS format:
sed -i 's|\r||' packages.txt

The pipe operator sends the stdout of one application into the next (as stdin. Unfortunately, apt-get does not read from stdin. Rather, apt-get takes a list of packages on the command line. I think what you are attempting to do is more along the lines of
apt-get install $(cat packages.txt | tr '\n' ' ')
or
apt-get install `cat packages.txt | tr '\n' ' '`
Which is to say evaluate the file list, and pass it in as an arguments to a single apt-get call.

Related

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

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!

Most efficient way to get the latest version of an rpm via web

This is my attempt using wget to pull down the web page, dig for latest tar file and rerun a wget to take it down. In the example, i'm taking down pip.
wget https://pypi.org/project/pip/#files
wget $(grep tar.gz index.html | head -1 | awk -F= '{print $2}' | sed 's/>//' | sed 's/\"//g')
gunzip -c $(ls | grep tar |tail -1) | tar xvf -
yum install -y python-setuptools
cd $(ls -d */ | grep pip)
python setup.py install
cd ..
I'm sure that there is a better way, perhaps only using one wget or similar
Do you mean like that?
wget $(curl -s "https://pypi.org/project/pip/#files"|grep -o 'https://[^"]*tar\.gz')

Why this command destroyed my ubuntu 14:04 installation?

I successfully used this command to remove all the old kernels from my system:
dpkg --list |
grep linux-image |
awk '{ print $2 }' |
sort -V |
sed -n '/'"linux-image-3.13.0-100-generic"'/q;p' |
xargs sudo apt-get -y purge
But when I used this modified version to un-install cups, dpkg started to remove packages unrelated to cups:
dpkg --list |
grep cups |
awk '{ print $2 }' |
sort -V |
xargs sudo apt-get -y purge
By the time I realized what was happening, my system had became already unbootable. I don't know if it's supposed to happen with xargs, but I could not stop the execution with a Ctrl+C sequence.

BASH automatically adding quotes to string

I'm trying to write a simple bash script that executes a command with one string variable. Upon execution bash adds single quotes to the string variable making the command useless. How do I execute the command without the quotes from the bash script?
#!/bin/bash
key=$(echo $1 | tr '[:lower:]' '[:upper:]')
sudo tee /proc/acpi/bbswitch \<\<\<$key
the output I get is
~/scripts$ bash -x nvidia on
++ echo on
++ tr '[:lower:]' '[:upper:]'
+ key=ON
+ sudo tee /proc/acpi/bbswitch '<<<ON'
the two commands I want to run without the quotes are either
sudo tee /proc/acpi/bbswitch <<<ON
or
sudo tee /proc/acpi/bbswitch <<<OFF
The problem isn't the quotes, it's that sudo doesn't execute the command via the shell. So metacharacters like <<< don't have any special meaning when they're given as sudo arguments. You need to invoke the shell explicitly:
sudo bash -c "tee /proc/acpi/bbswitch <<<$key"
But there doesn't really seem to be a need to use a here-string for this. Just use:
echo "$key" | sudo tee /proc/acpi/bbswitch
There's no need to quote the <<< operator. sudo doesn't read from its standard input by default; it passes it through to the command it runs.
sudo tee /proc/acpi/bbswitch <<< $key

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

Resources