How do I install cygwin components from the command line? - command-line

Is there a tool in the Cygwin package similar to apt-get on Debian or yum on redhat that allows me to install components from the command line?

Cygwin's setup accepts command-line arguments to install packages from the command-line.
e.g. setup-x86.exe -q -P packagename1,packagename2 to install packages without any GUI interaction ('unattended setup mode').
(Note that you need to use setup-x86.exe or setup-x86_64.exe as appropriate.)
See https://cygwin.com/packages/ for the package list.

For a more convenient installer, you may want to use
apt-cyg as your package manager. Its syntax similar to
apt-get, which is a plus. For this, follow the above
steps and then use Cygwin Bash for the following steps
wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg
chmod +x apt-cyg
mv apt-cyg /usr/local/bin
Now that apt-cyg is installed. Here are few examples of
installing some packages
apt-cyg install nano
apt-cyg install git
apt-cyg install ca-certificates

There is no tool specifically in the 'setup.exe' installer that offers the
functionality of apt-get. There is, however, a command-line package installer
for Cygwin that can be downloaded separately, but it is not entirely stable and
relies on workarounds.
apt-cyg: http://github.com/transcode-open/apt-cyg
Check out the issues tab for the project to see the known problems.

There exist some scripts, which can be used as simple package managers for Cygwin. But it’s important to know, that they always will be quite limited, because of...ehm...Windows.
Installing or removing packages is fine, each package manager for Cygwin can do that. But updating is a pain since Windows doesn’t allow you to overwrite an executable, which is currently running. So you can’t update e.g. Cygwin DLL or any package which contains the currently running executable from the Cygwin itself. There is also this note on the Cygwin Installation page:
"The basic reason for not having a more full-featured package manager is that
such a program would need full access to all of Cygwin’s POSIX functionality.
That is, however, difficult to provide in a Cygwin-free environment, such as
exists on first installation. Additionally, Windows does not easily allow
overwriting of in-use executables so installing a new version of the Cygwin
DLL while a package manager is using the DLL is problematic."
Cygwin’s setup uses Windows registry to overwrite executables which are in use
and this method requires a reboot of Windows. Therefore, it’s better to close
all Cygwin processes before updating packages, so you don’t have to reboot
your computer to actually apply the changes. Installation of a new package
should be completely without any hassles. I don’t think any of package managers
except of Cygwin’s setup.exe implements any method to overwrite files in use,
so it would simply fail if it cannot overwrite them.
Some package managers for Cygwin:
apt-cyg
Update: the repository was disabled recently due to copyright issues (DMCA takedown). It looks like the owner of the repository issued the DMCA takedown on his own repository and created a new project called Sage (see bellow).
The best one for me. Simply because it’s one of the most recent. It doesn’t use Cygwin’s setup.exe, it rather re-implements, what setup.exe does. It works correctly for both platforms - x86 as well as x86_64. There are a lot of forks with more or less additional features. For example, the kou1okada fork is one of the improved versions, which is really great.
apt-cyg is just a shell script, there is no installation. Just download it (or clone the repository), make it executable and copy it somewhere to the PATH:
chmod +x apt-cyg # set executable bit
mv apt-cyg /usr/local/bin # move somewhere to PATH
# ...and use it:
apt-cyg install vim
There is also bunch of forks with different features.
sage
Another package manager implemented as a shell script. I didn't try it but it actually looks good.
It can search for packages in a repository, list packages in a category, check dependencies, list package files, and more. It has features which other package managers don't have.
cyg-apt
Fork of abandoned original cyg-apt with improvements and bugfixes. It has quite a lot of features and it's implemented in Python. Installation is made using make.
Chocolatey’s cyg-get
If you used Chocolatey to install Cygwin, you can install the package cyg-get, which is actually a simple wrapper around Cygwin’s setup.exe written in PowerShell.
Cygwin’s setup.exe
It also has a command line mode. Moreover, it allows you to upgrade all installed packages at once (as apt-get upgrade does on Debian based Linux).
Example use:
setup-x86_64.exe -q --packages=bash,vim
You can create an alias for easier use, for example:
alias cyg-get="/cygdrive/d/path/to/cygwin/setup-x86_64.exe -q -P"
Then you can, for example, install Vim package with:
cyg-get vim

First, download installer at: https://cygwin.com/setup-x86_64.exe (Windows 64bit), then:
# move installer to cygwin folder
mv C:/Users/<you>/Downloads/setup-x86_64.exe C:/cygwin64/
# add alias to bash_aliases
echo "alias cygwin='C:/cygwin64/setup-x86_64.exe -q -P'" >> ~/.bash_aliases
source ~/.bash_aliases
# add bash_aliases to bashrc if missing
echo "source ~/.bash_aliases" >> ~/.profile
e.g.
# install vim
cygwin vim
# see other options
cygwin --help

I wanted a solution for this similar to apt-get --print-uris, but unfortunately apt-cyg doesn't do this. The following is a solution that allowed me to download only the packages I needed, with their dependencies, and copy them to the target for installation. Here is a bash script that parses the output of apt-cyg into a list of URIs:
#!/usr/bin/bash
package=$1
depends=$( \
apt-cyg depends $package \
| perl -ne 'while ($x = /> ([^>\s]+)/g) { print "$1\n"; }' \
| sort \
| uniq)
depends=$(echo -e "$depends\n$package")
for curpkg in $depends; do
if ! grep -q "^$curpkg " /etc/setup/installed.db; then
apt-cyg show $curpkg \
| perl -ne '
if ($x = /install: ([^\s]+)/) {
print "$1\n";
}
if (/\[prev\]/) {
exit;
}'
fi
done
The above will print out the paths of the packages that need downloading, relative to the cygwin mirror root, omitting any packages that are already installed. To download them, I wrote the output to a file cygwin-packages-list and then used wget:
mirror=http://cygwin.mirror.constant.com/
uris=$(for line in $(cat cygwin-packages-list); do echo "$mirror$line"; done)
wget -x $uris
The installer can then be used to install from a local cache directory. Note that for this to work I needed to copy setup.ini from a previous cygwin package cache to the directory with the downloaded files (otherwise the installer doesn't know what's what).

Old question, but still relevant. Here is what worked for me today (6/26/16).
From the bash shell:
lynx -source rawgit.com/transcode-open/apt-cyg/master/apt-cyg > apt-cyg
install apt-cyg /bin

Dawid Ferenczy's answer is pretty complete but after I tried almost all of his options I've found that the Chocolatey’s cyg-get was the best (at least the only one that I could get to work).
I was wanting to install wget, the steps was this:
choco install cyg-get
Then:
cyg-get wget

Usually before installing a package one has to know its exact name:
# define a string to search
export to_srch=perl
# get html output of search and pick only the cygwin package names
wget -qO- "https://cygwin.com/cgi-bin2/package-grep.cgi?grep=$to_srch&arch=x86_64" | \
perl -l -ne 'm!(.*?)<\/a>\s+\-(.*?)\:(.*?)<\/li>!;print $2'
# and install
# install multiple packages at once, note the
setup-x86_64.exe -q -s http://cygwin.mirror.constant.com -P "<<chosen_package_name>>"

Related

Using local Perl module instead of one installed by CPAN

I have found it necessary to expand upon a CPAN module. (Unicode::CharName goes up to Unicode 4.1; I need some characters from Unicode 5.0 & 5.1).
I've made the changes needed and have my own CharName.pm module.
I now would like to use it with my various Perls. I currently use:
Strawberry Perl for Windows
git for Windows MINGW64; My .bashrc sets
$PATH to Strawberry perl and $PERL5LIB=/c/Strawberry/perl/vendor/lib:/c/Strawberry/perl/site/lib
WSL Ubuntu
Where should I put my version of Unicode::CharName, so that it over-rides the ones installed by CPAN?
I don't want to have to change any scripts that currently
use Unicode::CharName;
Using cpanm you could download the module, patch it, and install it as normal:
$ cpanm --look Unicode::CharName
# new shell opens
$ patch lib/Unicode/CharName.pm custom.patch # or whatever process
$ perl Makefile.PL
$ make install
$ exit
You can also install it to a local::lib to avoid overwriting it globally, by adding the -l local/ option to the cpanm command. Then you can add the absolute path of this local::lib to your PERL5LIB or via -I or use lib. If you specified /path/to/local for the -l option, it would be /path/to/local/lib/perl5.
Manually copying files rather than going through the normal installation process is likely to lead to problems. Many distributions depend on the installation process to build the modules correctly. Also, you will need to install the module separately for each Perl you want to use it for; installed Perl modules are not generally cross-compatible between Perl versions or architectures. (A strictly simple pure-Perl module can be an exception to these rules, but the only module I feel comfortable abusing this way is App::cpanminus, because it was designed to do this.)

Fastest, cheapest way to create a fresh, throw-away installation of perl using perlbrew?

I tried doing the following. First, I install a relocatable perl, e.g.:
% perlbrew -Duserelocatableinc -j4 -n --as perl-5.28.1-fresh_src 5.28.1
Then, whenever I need a new throw-away fresh installation of perl to test things out, I do:
% cp -la ~/perl5/perlbrew/perls/perl-5.28.1-fresh{_src,1}
% perlbrew switch 5.28.1-fresh1
(then would later create fresh2, fresh3 and so on as needed; and when I want to throw these away I just rm -rf ~/perl5/perlbrew/perls/*fresh1 and so on.)
However, something (cpanm? EUMM?) is still confused. Scripts installed from CPAN still has the original perl path (in this case, /home/USER/perl5/perlbrew/perls/perl-5.28.1-fresh_src/bin) in their shebang line.
Any hint to the problem above, or an alternative way to quickly create a fresh throw-away perl installation is appreciated. Also, would the -l (--link) option of cp in the above command cause issue (other than perllocal.pod being appended and will contain installation records of perl installations, which is fine for me)?
It's not quite the same, but I find docker works if I'm needing a clean install for certain testing scenarios - build up a base image and a clean perl install, fire up the container and run 'whatever'.
You'll need root access and be able to install packages (e.g. docker) so it's not going to be suitable for every use case.
https://buildlogs.centos.org/centos/7/docker/ has a base image you can use to build a 'clean' CentOS (or use whatever OS you prefer frankly - most have container versions)
FROM scratch
ADD CentOS-7-20140625-x86_64-docker_01.img.tar.xz
LABEL name="CentOS Base Image"
CMD ["/bin/bash"]
In the working directory:
docker build -t mycentos .
This will give you a very basic image:
Then your perl dockerfile:
FROM mycentos
COPY local.repo /etc/yum.repos.d/local.repo
RUN yum clean all
RUN yum install --nogpgcheck -y make gcc tar
ADD perl-5.28.1.tar.gz /build/
RUN cd /build/perl-5.28.1 && ./Configure -de
RUN cd /build/perl-5.28.1 && make && make test && make install
COPY MyConfig.pm /root/.cpan/CPAN/MyConfig.pm
RUN cpan install Bundle::CPAN
CMD ["/bin/bash"]
You'll be able to spin this up, with e.g. docker run and invoke a script using /usr/local/bin/perl.
It's not quite what you asked for, but your base image can be started and discarded as you wish - you can maintain image for a few different OS and perl combinations too.

Installing cpan or cpanm modules on a behind-firewall machine with no Internet connection

I've already read related threads like these, but they do not fully capture our situation.
This is on a firewalled machine. No net access. We can ftp files to folders and install modules from there.
We have CHMOD 777 for our users on some folders. We can install Perl modules if we locally build them by downloading the relevant .pm files. But when these files cannot install, we do not have any cpan or cpanm.
I'd like to install, for example, HTML::Restrict. If I do the download + install thing, the Restrict.pm gives me this error:
/lib/HTML/Restrict.PM:328: Unknown command paragraph "=encoding UTF-8"
Reading a bit online suggests that this could be an old Perl problem. We use 5.8.x. Our own dev machines have the luxury of 5.16.x and internet access so installing module is a cinch. Anyway, one of my older machines also has 5.8.x, and installing the module via cpanminus worked there (with internet).
So, question: is it possible to install "cpanminus" (cpanm) through FTP, then upload specific module files to the server through FTP too, and then go into shell and install modules via cpanm by pointing it to respective .pm files?
Thank you for any pointers.
You should take a look at perldoc perlmodinstall which goes into detail about how to install a module from its distribution. It follows what should be a familiar incantation
Decompress
Unpack
Build
Test
Install
Assuming you're on a Linux system, this commonly takes take the form of
gzip -d My-Module-Distribution.tar.gz
tar -xof My-Module-Distribution.tar
perl Makefile.PL
make
make test
make install
But after the Unpack stage you will often find a README file or other text file that will describe any unusual steps to be taken
Clearly some of these steps can be combined. For instance, most people will probably want to use
tar -xvfz My-Module-Distribution.tar.gz
to avoid having to invoke gzip separately. Likewise, the make system will force a build phase as a prerequisite if you use just
make test
without the preceding make
The linked document has a lot to say about how to install on other platforms, should you not be running a Linux variant
I still don't really understand your thinking, but you can get a stand-alone version of cpanm using curl. For instance
curl -sS --location https://cpanmin.us/ --output cpanm
then you should be able to just copy it to your target machine, put it on your PATH, and do
cpanm HTML-Restrict-2.2.2.tar.gz
but I doubt if you will find any change to the specific errors you are getting

Uninstall all perl modules installed by cpan

Yesterday I wanted to test some software and in the documentation it said, to install I just needed to type
cpan -i Software
I never used cpan, I just know that it is the perl package manager. (Is it..?) However, it turned out that I needed loads of dependencies, and stupid as I am, I just installed all of them. (First, I had to set up cpan which asked me lots of questions) Long story short, I just want to remove all of it again. I googled a bit, and it seems like cpan does not have an uninstall routine, especially for all the packages at once.
Can I just remove some directory or will I run into troubles?
the cpan command isn't really a package manager like apt-get is. It is more a tool that downloads and installs from CPAN (the site, or one of its mirrors). After it has finished this task it doesn't remember much about what was done before, at least not enough to remove previously installed modules, at least not reliably, cleanly or dependency-safely. (Update: After looking at App::pmuninstall, it can be used to handle dependencies, but it does so by connecting to outside (read: web) sources, which compute these separately, which is fine, but I stand by the previous statement that CPAN.pm doesn't do this.)
I used to worry about removing modules, but now I realize that most Perl modules take up so little room that I just don't worry about having a few extra modules installed that you will never use. So unless you are on a computer with a REALLY small disc, I would just let it be.
On Windows or if you are using a non-system Perl on Linux/Mac you could just remove Perl and reinstall it. I would not recommend this if you are using the system installed Perl on Linux/Mac however as you could break your OS doing this (you might be ok if you were careful, but not worth it to save a few Mb!).
In the future, you can easily install a local version of Perl using perlbrew, there are tutorials all over the web if the docs aren't sufficient (they should be). This also has the bonus of letting you play with the newest and greatest Perl versions, which your system likely doesn't come with yet. Then if you install a mountain of junk, or even break it doing something crazy, remove that version and reinstall/install a different version.
Another nice tool is cpanminus (or cpanm for short) which is a newer, more user friendly cpan tool. All the cool kids are using it.
You can uninstall individual modules with cpanplus (ships with Perl) like this:
cpanp uninstall SQL::Abstract
You can view all modules installed with the cpan script like this:
perldoc perllocal
Putting the two together:
for module in $(perldoc -u perllocal | grep -F 'C<Module> L<' | sed 's/^.*L<\(.*\)|.*>$/\1/') ; do
cpanp uninstall "$module"
done
I'm not sure about removing "all of it". But to remove a single module you can use App::pmuninstall with it's sole script pm-uninstall to uninstall modules. You might then be able to write some kind of script to recursively remove the deps.
If you can't use cpan any more because there are incompatible modules in you path, you can remove all installed modules by hand. For example, I upgraded from Fedora 22 to Fedora 23 and the Perl version changed. All modules installed previously via cpanm into /usr/local/lib64/perl5 did not work any more and prevented me from using cpanm.
$ cpanm --uninstall Apache::DBI
Attempt to reload Scalar/Util.pm aborted.
Compilation failed in require at /usr/share/perl5/vendor_perl/File/Temp.pm line 18.
...
I could solve this by moving that directory:
$ mv /usr/local/lib64/perl5 /root/usr-local-lib64-perl5
The name of that directory may vary on your system.
Carefull: If a module installed files outside of that directory, for example system library files, these files will remain there.
I will change Flimm's answer to use cpanm and optionally uninstall cpanm itself in the end of the script:
#!/usr/bin/env bash
for module in $(perldoc -u perllocal | grep -F 'C<Module> L<' | sed 's/^.*L<\(.*\)|.*>$/\1/' | sort | uniq) ; do
if [[ "$module" =~ "App::cpanminus" ]]; then
continue
fi
echo "Uninstalling $module..."
yes | cpanm --uninstall "$module"
done
cpanm --uninstall App::cpanminus
I think the best option is uninstall Perl and install it again.

How can I install Perl modules without root privileges?

I am on a Linux machine where I have no root privileges. I want to install some packages through CPAN into my home directory so that when I run Perl, it will be able to see it.
I ran cpan, which asked for some coniguration options. It asked for some directory, which it suggested ~/perl "for non-root users". Still, when I try to install a package, it fails at the make install step, because I don't have write access to /usr/lib/perl5/whatever.
How can I configure CPAN so that I can install packages into my home directory?
See local::lib.
Once you have it installed, you can do:
perl -MCPAN -Mlocal::lib -e 'CPAN::install(LWP)'
There's the way documented in perlfaq8, which is what local::lib is doing for you.
It's also a frequently asked StackOverflow question:
Why does installing certain CPAN modules require root privilege?
How can I install CPAN modules locally without root access (DynaLoader.pm line 229 error)?
How do I tell CPAN.pm to install all modules in a specific directory?
How can I install a CPAN module into a local directory?
How can I use a new Perl module without install permissions?
How can I use CPAN as a non-root user?
How can I install local modules with the cpan tool?
Curiously, none of these are suggested when I use your original question title (which is one of the reasons a good title is very important in finding your answer).
How do I keep my own module/library directory?
When you build modules, tell Perl where to install the modules.
If you want to install modules for your own use, the easiest way might be local::lib, which you can download from CPAN. It sets various installation settings for you, and uses those same settings within your programs.
If you want more flexibility, you need to configure your CPAN client for your particular situation.
For Makefile.PL-based distributions, use the INSTALL_BASE option when generating Makefiles:
perl Makefile.PL INSTALL_BASE=/mydir/perl
You can set this in your CPAN.pm configuration so modules automatically install in your private library directory when you use the CPAN.pm shell:
% cpan
cpan> o conf makepl_arg INSTALL_BASE=/mydir/perl
cpan> o conf commit
For Build.PL-based distributions, use the --install_base option:
perl Build.PL --install_base /mydir/perl
You can configure CPAN.pm to automatically use this option too:
% cpan
cpan> o conf mbuild_arg "--install_base /mydir/perl"
cpan> o conf commit
INSTALL_BASE tells these tools to put your modules into /mydir/perl/lib/perl5. See How do I add a directory to my include path (#INC) at runtime? for details on how to run your newly installed modules.
There is one caveat with INSTALL_BASE, though, since it acts differently than the PREFIX and LIB settings that older versions of ExtUtils::MakeMaker advocated. INSTALL_BASE does not support installing modules for multiple versions of Perl or different architectures under the same directory. You should consider if you really want that, and if you do, use the older PREFIX and LIB settings. See the ExtUtils::Makemaker documentation for more details.
CPAN way
run cpan command. If you don't have CPAN configurated, do it first! Otherwise, you will see the cpan prompt. In this case, type look local::lib and you will have a new shell prompt. In this new shell, run the bootstrap command configuring and compiling the module at same time as at bellow.
user#host:~/.cpan/build/local-lib-1.004003-UyX2wf$ perl Makefile.PL --bootstrap && make test && make install
Now, export some variables:
Path where local::lib will install things
echo 'eval $(perl -I$index.t/perl5/lib/perl5 -Mlocal::lib)' >> ~/.bashrc
And Perl variable to avoid user input
echo 'export PERL_MM_USE_DEFAULT=1' >> ~/.bashrc
Now load your bashrc running
source ~/.bashrc
Try to install running cpan <SOME_VALID_MODULE_NAMESPACE>
That's it! Now you can install modules using cpan without root privileges. But, remember that this will work just for the CURRENT USER including the root user !
cpanminus way
If you have this installed your sys admin deserves a beer!
Just run
$ cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
Open another terminal and run
$ env |grep PERL
You should see something like this:
PERL5LIB=$HOME/perl5/lib/perl5 PERL_MB_OPT=--install_base "$HOME/perl5"
PERL_LOCAL_LIB_ROOT=$HOME/perl5
PERL_MM_OPT=INSTALL_BASE=$HOME/perl5
But if you're not, export variables like this:
$ echo "export PERL5LIB=\"$HOME/perl5/lib/perl5\"">>~/.bashrc && \
echo "export PERL_MB_OPT=\"--install_base '$HOME/perl5'\">>~/.bashrc && \
echo "export PERL_LOCAL_LIB_ROOT=$HOME/perl5">>~/.bashrc
Finally, load your bashrc file and try to install with commands
source ~/.bashrc
and
cpanm <SOME_VALID_MODULE_NAMESPACE>
Fim!