https://wiki.archlinux.org/api.php?action=feedcontributions&user=Nedludd&feedformat=atomArchWiki - User contributions [en]2024-03-29T15:43:52ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Haskell&diff=653239Haskell2021-02-23T16:08:52Z<p>Nedludd: /* Stack */ Minor grammar change</p>
<hr />
<div>[[Category:Programming languages]]<br />
[[ja:Haskell]]<br />
[[ru:Haskell]]<br />
{{Related articles start}}<br />
{{Related|Haskell package guidelines}}<br />
{{Related articles end}}<br />
<br />
From [[Wikipedia:Haskell (programming language)|Wikipedia]]:<br />
:[http://www.haskell.org Haskell] is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Developed to be suitable for teaching, research and industrial application, Haskell has pioneered a number of advanced programming language features such as type classes, which enable type-safe operator overloading. Haskell's main implementation is the Glasgow Haskell Compiler (GHC). It is named after logician Haskell Curry.<br />
<br />
== Installation ==<br />
<br />
{{Note|There are several choices for Haskell installation, one is supported by Arch Linux, while others are officially supported by Haskell for any Linux distributions. This article describes Arch way of installing and using Haskell. See [[#Alternate installations]] for more information about other installation methods.}}<br />
<br />
Haskell generates machine code that can be run natively on Linux. There is nothing special required to run a binary (already compiled) software, like {{Pkg|xmonad}} or {{Pkg|pandoc}} provided in the [[official repositories]]. On the other side, building [[AUR]] packages or developing software require a compiler and build tools to be installed.<br />
<br />
To install the latest version of Haskell, [[install]] the following packages from the official repositories:<br />
* {{Pkg|ghc}} ([https://www.haskell.org/ghc GHC]) — A Haskell compiler. There are several [https://www.haskell.org/haskellwiki/Implementations implementations] available, but the one used most (which is now ''de facto'' the reference) is the GHC (Glasgow Haskell Compiler).<br />
* {{Pkg|cabal-install}} ([https://www.haskell.org/cabal Cabal]) — A build tool focused on dependency resolution and sources packages from [https://hackage.haskell.org Hackage]. Hackage is the Haskell community's central package archive of open source software.<br />
* {{Pkg|stack}} ([https://www.haskellstack.org Stack]) — A build tool focused on curated snapshots and sources packages from [https://www.stackage.org Stackage]. Stackage is a stable subset of Hackage that provides curated sets (snapshots) of packages known to work well with each other. Alternatively, Stack can be installed through {{AUR|stack-static}} package. It provides statically linked binaries, thereby avoiding dozens of {{ic|haskell-*}} dependencies.<br />
<br />
You can install and configure either Cabal or Stack or both of them. Most of the popular Haskell packages support both Cabal and Stack.<br />
<br />
== Configuration ==<br />
<br />
Since version [https://github.com/archlinux/svntogit-community/commit/7a948cdfb808afd3ce6f93047ae0dc1778e79f9f 8.0.2-1], the Arch {{Pkg|ghc}} package and all [https://archlinux.org/packages/?q=haskell haskell-*] packages in ''community'' provide only dynamically linked libraries. Therefore, to link successfully one must configure GHC, Cabal and Stack for dynamic linking, as the default is to use static linking.<br />
<br />
Using dynamic linking typically results in faster builds and smaller disk and RAM usage (by sharing pages between multiple running Haskell programs), and will free you from troubleshooting cross-GHC mixing errors. But it has its own disadvantage: '''all tools you install from source will break''' on every update of {{Pkg|ghc}}, {{Pkg|ghc-libs}} or [https://archlinux.org/packages/?q=haskell haskell-*] packages since libraries compiled with GHC do not provide a stable [[Wikipedia:Application binary interface|ABI]]. When running such broken binary, you will see the usual message {{ic|error while loading shared libraries: libHS...so: cannot open shared object file: No such file or directory}}. To fix this, just rebuild and reinstall the broken tool in order to relink it to newer libraries.<br />
<br />
On the other hand, static linking is generally easier to maintain and does not force you to rebuild all tools from source after every update of their dependencies. For these reasons, static linking is often the preferred option for local development outside of the package system. If you prefer static linking, see [[#Static linking]] or [[#Alternate installations]] for details.<br />
<br />
{{Note|For a detailed explanation of why Arch moved to dynamic linking for Haskell packages, see this [https://www.reddit.com/r/linux/comments/9emwtu/arch_linux_ama/e5qssdz maintainer's response].}}<br />
<br />
=== Invoking GHC directly ===<br />
<br />
In order to link successfully one must pass the {{ic|-dynamic}} flag to GHC. You can try it with the following file:<br />
<br />
{{hc|Main.hs|2=<br />
main = putStrLn "Hello, World"<br />
}}<br />
<br />
Compile and run it with:<br />
<br />
{{hc|<br />
$ ghc -dynamic Main.hs<br />
$ ./Main|<br />
Hello, World<br />
}}<br />
<br />
=== Configuring Cabal for dynamic linking ===<br />
<br />
First, run the following command to download the latest list of packages from Hackage and create global configuration file {{ic|~/.cabal/config}} (or the file {{ic|$CABAL_CONFIG}} points to):<br />
<br />
$ cabal update<br />
<br />
{{Tip|It is advisable to periodically run {{ic|cabal update}} to synchronize your local list of packages and dependencies with the newest version on Hackage.}}<br />
<br />
To configure Cabal for dynamic linking, uncomment and edit the following options in {{ic|~/.cabal/config}}:<br />
<br />
{{hc|~/.cabal/config|<br />
library-vanilla: False<br />
shared: True<br />
executable-dynamic: True<br />
program-default-options<br />
ghc-options: -dynamic<br />
}}<br />
<br />
* {{ic|library-vanilla: False}} suppresses the creation of static libraries (if your project contains a library).<br />
* {{ic|shared: True}} enables the creation of shared libraries (if your project contains a library).<br />
* {{ic|executable-dynamic: True}} causes dynamic linking to be used for executables (if your project contains executables).<br />
* {{ic|ghc-options: -dynamic}} adds the {{ic|-dynamic}} flag to every invocation of GHC (e.g. if a package has a non-trivial {{ic|Setup.hs}}).<br />
<br />
=== Configuring Stack for dynamic linking ===<br />
<br />
You can use {{ic|stack setup}} command to initialize Stack and create global configuration file {{ic|~/.stack/config.yaml}}. By default Stack will automatically download its own version of GHC to an isolated location upon first invocation. To force Stack to use system GHC installation instead, run {{ic|stack setup}} with {{ic|--system-ghc}} and {{ic|--resolver}} flags:<br />
<br />
$ stack setup --system-ghc --resolver ''resolver''<br />
<br />
Note that you need to specify a resolver which is compatible with your system GHC. Otherwise Stack will happily ignore {{ic|--system-ghc}} flag and download its own copy of GHC. You can determine the version of system GHC using {{ic|ghc --version}} command:<br />
<br />
{{hc|$ ghc --version|<br />
The Glorious Glasgow Haskell Compilation System, version 8.10.2<br />
}}<br />
<br />
Then visit [https://www.stackage.org Stackage] website and pick a suitable Long Term Support (LTS) or nightly snapshot matching your system GHC version. Use the selected snapshot for {{ic|--resolver}} flag on the command line, e.g. {{ic|--resolver lts-16.15}} or {{ic|--resolver nightly-2020-09-01}}.<br />
<br />
Stackage typically lags behind new GHC releases. It may happen that no Stackage snapshot for your system GHC has yet been released. In this case you might want to choose a snapshot for some earlier minor version of GHC or temporarily downgrade your Haskell installation and wait until support for newer GHC releases finally lands on Stackage.<br />
<br />
To configure Stack for dynamic linking, add the following snippet to {{ic|~/.stack/config.yaml}}:<br />
<br />
{{hc|~/.stack/config.yaml|<br />
# Stop downloading GHCs into isolated locations under ~/.stack.<br />
install-ghc: false<br />
<br />
# Allow Stack to pick the system GHC (false by default).<br />
system-ghc: true<br />
<br />
# Allow to use, say, Stackage snapshot for GHC 8.8.2 with system GHC 8.8.3.<br />
compiler-check: newer-minor<br />
<br />
# Add the -dynamic flag to every invocation of GHC.<br />
ghc-options:<br />
"$everything": -dynamic<br />
}}<br />
<br />
== Package management ==<br />
<br />
Most of Haskell libraries and executables are distributed in units of source packages available from Hackage and Stackage.<br />
<br />
As is common in other compiled languages, a number of popular Haskell packages are available from official Arch repositories in pre-built form. Some additional packages can be installed from [[AUR]].<br />
<br />
Although it is recommended to use [[pacman]] to install GHC, libraries and tools from official repositories — at some point you may want to install Haskell packages directly from Hackage/Stackage or compile your own (or somebody else's) packages from source. You will need Cabal or Stack for doing that.<br />
<br />
The following table summarizes the advantages and disadvantages of different package management styles.<br />
<br />
{| class="wikitable"<br />
! '''Method'''<br />
! '''Pros'''<br />
! '''Cons'''<br />
|-<br />
| Official repositories || Provided by Arch Linux developers, consistent versions of packages, already compiled || Not all packages available, only dynamic libraries available<br />
|-<br />
| Cabal || All packages available, root not required || Installed in home directory, failures in dependency resolution, difficult to remove specific packages<br />
|-<br />
| Stack || All packages available (favors Stackage), root not required || Installed in home directory, versions are pinned to snapshot, difficult to remove specific packages<br />
|-<br />
| AUR || Additional packages available || Risk of unmaintained or orphaned packages, incompatible versions of packages possible<br />
|-<br />
|}<br />
<br />
=== Cabal ===<br />
<br />
{{Note|In Haskell, the term ''Cabal'' can refer to either:<br />
* Cabal file format that describes Haskell packages and their dependencies;<br />
* Cabal library that works with Cabal file format;<br />
* {{ic|cabal}} command-line tool (provided by {{Pkg|cabal-install}} package) that uses Cabal library to build Haskell packages.<br />
In the context of this article, ''Cabal'' usually means {{ic|cabal}} command-line tool unless specified otherwise.}}<br />
<br />
Cabal is "the original" build system for Haskell. Most of libraries and tools you can find on Hackage can be installed via Cabal.<br />
<br />
==== Installing packages ====<br />
<br />
To run user-wide executables installed by Cabal, {{ic|~/.cabal/bin}} must be added to the {{ic|$PATH}} environment variable. This can be done by putting the following line in your shell configuration file, for instance {{ic|~/.bashrc}} for {{Pkg|bash}} or {{ic|~/.zshrc}} for {{Pkg|zsh}}:<br />
<br />
export PATH="$HOME/.cabal/bin:$PATH"<br />
<br />
Run the following command to install a Hackage package and all of its dependencies in a single step:<br />
<br />
$ cabal install --ghc-options=-dynamic ''package''<br />
<br />
{{Note|As of October 2020 Cabal [https://github.com/haskell/cabal/issues/6505 ignores] {{ic|ghc-options}} from {{ic|~/.cabal/config}} while building packages with {{ic|build-type: Custom}}. Therefore, it is necessary to specify {{ic|1=--ghc-options=-dynamic}} flag on the command line otherwise you might experience build errors in {{ic|setup.hs}} like {{ic|Could not find module ‘Prelude’ There are files missing in the ‘base-...’ package}}.}}<br />
<br />
You can also build and install a Haskell package from source. To do this, run the following command from the package directory:<br />
<br />
$ cabal install --ghc-options=-dynamic<br />
<br />
Each Cabal package should specify a list of its dependencies and their version constraints in the {{ic|.cabal}} file according to the [https://pvp.haskell.org Package Versioning Policy] (PVP). During the package installation, Cabal tries to find a set of dependencies that satisfies all the constraints. This process is called ''dependency resolution''.<br />
<br />
There are reasons why Stack exists; Cabal is known to generate a lot of friction with beginners. Most of the time dependency resolution works well but sometimes it fails. In this case you will need to figure out the cause of the problem and give Cabal some hints about how to resolve offending dependencies. For example, sometimes it is necessary to say {{ic|1=cabal install --allow-newer --ghc-options=-dynamic ''package''}} to allow Cabal to ignore package's PVP-dictated upper bounds on dependency versions, effectively installing package with newer dependencies than the package author has permitted. It gets hairier for less-well maintained packages; for another example, see [https://groups.google.com/d/msg/idris-lang/h2uWYmqHcc0/5k0jNmQ3BAAJ this thread] about installing Idris (another programming language, written in Haskell), where one had to use both {{ic|--allow-newer}} and {{ic|1=--constraint='haskeline < 0.8.0.0'}} command-line flags to get a successful compile.<br />
<br />
==== Removing packages ====<br />
<br />
There is no easy way to do it. Cabal does not have support for this functionality but there are external tools like [https://github.com/phadej/cabal-extras#cabal-store-gc cabal-store-gc].<br />
<br />
To reinstall the entire user-wide Haskell package system, remove {{ic|~/.cabal}} and {{ic|~/.ghc}} and start from scratch. This is often necessary when GHC is upgraded.<br />
<br />
For more precision, it's possible to use {{ic|ghc-pkg unregister ''package''}} or {{ic|ghc-pkg hide ''package''}}/{{ic|ghc-pkg expose ''package''}} directly on the [https://downloads.haskell.org/ghc/8.10.2/docs/html/users_guide/packages.html#package-databases|''user package database''] — this makes GHC "forget" about an installed package (or pretend it's not there). However neither of these removes any files.<br />
<br />
=== Stack ===<br />
<br />
Stack is another tool to manage Haskell packages. It has slightly different goals than Cabal, with a slightly different philosophy. It uses Cabal library under the hood and integrates with Hackage — but maintains its own repositories of packages (snapshots) on Stackage with the promise that snapshots are curated and include packages which work well together.<br />
<br />
==== Installing packages ====<br />
<br />
In its default configuration, Stack installs compiled executables to {{ic|~/.local/bin}}. Add this directory to the {{ic|$PATH}} environment variable in your shell configuration file, for instance {{ic|~/.bashrc}} for {{Pkg|bash}} or {{ic|~/.zshrc}} for {{Pkg|zsh}}:<br />
<br />
export PATH="$HOME/.local/bin:$PATH"<br />
<br />
Run the following command to download, build and install a Stackage package:<br />
<br />
stack install ''package''<br />
<br />
{{Note|As of October 2020 Stack [https://github.com/commercialhaskell/stack/issues/3409 ignores] {{ic|ghc-options}} from {{ic|~/.stack/config.yaml}} while building {{ic|Setup.hs}}. If you experience build errors in {{ic|Setup.hs}} like {{ic|Could not find module ‘Prelude’ There are files missing in the ‘base-...’ package}}, try to install {{Pkg|ghc-static}} package as a workaround.}}<br />
<br />
You can also build and install a Haskell package from source by running the following command from the package directory:<br />
<br />
stack install --resolver ''resolver''<br />
<br />
Note that you should specify the same resolver as one used for {{ic|stack setup}} command.<br />
<br />
==== Removing packages ====<br />
<br />
Stack does not support the "uninstall" operation.<br />
<br />
If you want to reinstall the entire user-wide Haskell package system, remove {{ic|~/.stack}} directory and start from scratch. This is often necessary when GHC is upgraded.<br />
<br />
== Alternate installations ==<br />
<br />
{{Note|This section describes alternative ways of installing Haskell on Arch without using packages from the official repositories. If you previously installed GHC, Cabal, Stack or any other Haskell packages, make sure to uninstall them first. Remove {{ic|~/.cabal}} and {{ic|~/.stack}} directories if they exist.}}<br />
<br />
There are two officially recommended methods of installing Haskell on any generic Linux distribution: [https://gitlab.haskell.org/haskell/ghcup-hs ghcup] and [https://www.haskellstack.org Stack]. Both methods install statically linked GHC, tools and libraries in your home directory.<br />
<br />
The advantage of using ghcup or Stack instead of Haskell packages from the official repositories is the ability to install and manage multiple versions of GHC side by side. Cabal and Stack installed this way typically work right out of the box without any additional configuration, which might be easier for beginners.<br />
<br />
A completely different way of installing Haskell is [[Nix]] package manager. Nix has a steeper learning curve but offers greater flexibility in managing both Haskell and non-Haskell packages in a reliable and reproducible fashion.<br />
<br />
=== ghcup ===<br />
<br />
ghcup is a command line tool that allows to easily install multiple versions of GHC and switch between them. It is similar in scope to [https://github.com/rust-lang/rustup rustup], [https://github.com/pyenv/pyenv pyenv] and [https://www.jenv.be jenv].<br />
<br />
Install {{AUR|ghcup-hs-bin}} package. Alternatively, you may follow official [https://www.haskell.org/ghcup installation instructions] or manually download [https://downloads.haskell.org/~ghcup ghcup binary] and place it somewhere into your {{ic|$PATH}}.<br />
<br />
By default, ghcup will install GHC executables into {{ic|~/.ghcup/bin}}. You need to add this directory to the {{ic|$PATH}} environment variable in your shell configuration file, for instance {{ic|~/.bashrc}} for {{Pkg|bash}} or {{ic|~/.zshrc}} for {{Pkg|zsh}}. If you want to run executables installed by Cabal, add {{ic|~/.cabal/bin}} to {{ic|$PATH}} as well:<br />
<br />
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"<br />
<br />
{{Tip|If you want to use XDG style directories, define {{ic|GHCUP_USE_XDG_DIRS}} environment variable (https://gitlab.haskell.org/haskell/ghcup-hs/#xdg-support).}}<br />
<br />
ghcup provides a convenient TUI which supports most of its functionality:<br />
<br />
$ ghcup tui<br />
<br />
Alternatively, you can use the following CLI commands:<br />
<br />
List available versions of GHC and Cabal:<br />
<br />
$ ghcup list<br />
<br />
Install the recommended version of GHC:<br />
<br />
$ ghcup install ghc<br />
<br />
You can also install a specific version of GHC, for example:<br />
<br />
$ ghcup install ghc 8.10.2<br />
<br />
The commands above do not automatically make GHC available on the {{ic|$PATH}}. You need to select which GHC version to use by default:<br />
<br />
$ ghcup set ghc 8.10.2<br />
<br />
Install the recommended version of Cabal:<br />
<br />
$ ghcup install cabal<br />
<br />
You can now use Cabal to build and install statically linked Haskell executables without any special configuration or command line flags:<br />
<br />
{{bc|<br />
$ cabal update<br />
$ cabal install ''executable''<br />
}}<br />
<br />
To start a new Cabal project:<br />
{{hc|<br />
$ cd /path/to/my-project<br />
$ cabal init<br />
$ cabal build<br />
$ cabal run|<br />
Up to date<br />
Hello, Haskell!<br />
}}<br />
<br />
For more information, refer to official [https://gitlab.haskell.org/haskell/ghcup-hs ghcup] and [https://cabal.readthedocs.io/en/latest Cabal] documentation.<br />
<br />
=== Stack ===<br />
<br />
Install {{AUR|stack-static}} package. Alternatively, you may follow official [https://docs.haskellstack.org/en/stable/install_and_upgrade installation instructions] or manually download [https://github.com/commercialhaskell/stack/releases Stack binary] and place it somewhere into your {{ic|$PATH}}.<br />
<br />
If you want to run executables installed by Stack, add {{ic|~/.local/bin}} directory to the {{ic|$PATH}} environment variable in your shell configuration file, for instance {{ic|~/.bashrc}} for {{Pkg|bash}} or {{ic|~/.zshrc}} for {{Pkg|zsh}}:<br />
<br />
export PATH="$HOME/.local/bin:$PATH"<br />
<br />
Run {{ic|stack setup}} to automatically install GHC from the latest Stackage LTS snapshot:<br />
<br />
$ stack setup<br />
<br />
You can now use Stack to build and install statically linked Haskell packages without any special configuration or command line flags:<br />
<br />
$ stack install ''package''<br />
<br />
For more information, refer to official [https://docs.haskellstack.org/en/stable Stack documentation].<br />
<br />
=== Nix ===<br />
<br />
{{Expansion|I cannot offer a good enough overview, due to no experience with it}}<br />
<br />
== IDE support ==<br />
<br />
=== Tools ===<br />
<br />
==== ghcid ====<br />
<br />
[https://github.com/ndmitchell/ghcid ghcid] provides a simple and robust way to display compiler messages on source code change.<br />
<br />
==== Linters ====<br />
<br />
[https://github.com/ndmitchell/hlint hlint] is a linter, suggesting possible improvements to Haskell code.<br />
<br />
[https://github.com/kowainik/stan stan] is another linter, complementary to hlint. It is in its early stages as of January 2021.<br />
<br />
==== haskell-language-server ====<br />
<br />
[https://github.com/haskell/haskell-language-server haskell-language-server] is a [https://microsoft.github.io/language-server-protocol/ Language Server Protocol] (LSP) implementation for Haskell. It provides IDE-like features like type-on-hover or autocompletions for any editor integrating with the LSP.<br />
<br />
There are pre-built binaries which can be installed via {{AUR|haskell-language-server-bin}}, [[#ghcup]] or by the [https://marketplace.visualstudio.com/items?itemName=haskell.haskell Haskell extension] for [[Visual Studio Code]].<br />
<br />
==== Formatters ====<br />
<br />
{| class="wikitable"<br />
! '''Formatter'''<br />
! '''Notes'''<br />
|-<br />
| [https://github.com/lspitzner/brittany brittany] ||<br />
|-<br />
| [https://github.com/ennocramer/floskell floskell] ||<br />
|-<br />
| [https://github.com/tweag/ormolu ormolu] || not configurable by design<br />
|-<br />
| [https://github.com/parsonsmatt/fourmolu fourmolu] || fork of ormolu, adding configurability<br />
|-<br />
| [https://github.com/jaspervdj/stylish-haskell stylish-haskell]<br />
|-<br />
|}<br />
<br />
=== Editors ===<br />
<br />
{{Expansion|I don't have experience with other editors}}<br />
<br />
==== Emacs ====<br />
<br />
Basic [[Emacs]] support for Haskell is provided by the official [https://github.com/haskell/haskell-mode haskell-mode]. For more advanced features, also use [https://github.com/emacs-lsp/lsp-haskell lsp-haskell] with [[#haskell-language-server]].<br />
<br />
==== Vim ====<br />
<br />
Any [https://vimawesome.com/?q=LSP LSP client] plugin will work with [[#haskell-language-server]].<br />
<br />
==== Visual Studio Code ====<br />
<br />
[[Visual Studio Code]] support is provided by the official [https://marketplace.visualstudio.com/items?itemName=haskell.haskell Haskell plugin].<br />
<br />
== Tips and tricks ==<br />
<br />
=== Static linking ===<br />
<br />
{{Note|This section explains how to build statically linked Haskell packages on Arch, but still use GHC installed from the official repositories. Before you proceed, make sure to remove {{ic|~/.cabal}} and {{ic|~/.stack}} directories if they exist.}}<br />
<br />
{{Note|In the context of this article, static linking does not mean generating completely static ELF binaries. Only Haskell code will be linked statically into a single ELF binary, which may be dynamically linked to other system libraries such as {{Pkg|glibc}}.}}<br />
<br />
To use static linking, one must, at minimum, install the static boot libraries through the {{Pkg|ghc-static}} package. This would allow you to build projects that depend exclusively on the boot libraries as well as on any other libraries that are not installed through the {{ic|haskell-*}} packages from the official repositories.<br />
<br />
Unfortunately, if your project depends on any of dynamically linked {{ic|haskell-*}} packages that you have installed, Cabal does not take the absence of static libraries into account during dependency resolution. As a result, it will try to use the existing {{ic|haskell-*}} package and then fail with [https://bugs.archlinux.org/task/54563#comment158808 linker errors] when it realizes the static libraries are missing. Unlike {{ic|ghc-static}}, there are no “{{ic|haskell-*-static}}” packages to fix this problem.<br />
<br />
There are multiple ways to work around this issue. One involves compilation of Haskell packages in a separate build environment provided by {{AUR|ghc-pristine}} package, while others use statically linked {{AUR|cabal-static}} or {{AUR|stack-static}} packages instead of their dynamically linked counterparts from the official repositories.<br />
<br />
==== ghc-pristine ====<br />
<br />
Install {{AUR|ghc-pristine}} package, which wraps over an existing GHC installation to create a separate GHC distribution in {{ic|/usr/share/ghc-pristine}}, with a package database that contains only boot libraries. This effectively creates a semi-isolated environment without dynamically linked {{ic|haskell-*}} packages, but still makes use of the GHC compiler from the official repositories. Then, to build software with static linking, one simply needs to invoke the wrapped compiler {{ic|/usr/share/ghc-pristine/bin/ghc}}. For Cabal, this amounts to the following configuration in {{ic|~/.cabal/config}}:<br />
<br />
{{hc|~/.cabal/config|<br />
with-compiler: /usr/share/ghc-pristine/bin/ghc<br />
}}<br />
<br />
You can also specify the path to the compiler on a per-project basis by running the following command from the project directory:<br />
<br />
$ cabal configure --with-compiler=/usr/share/ghc-pristine/bin/ghc<br />
<br />
==== cabal-static ====<br />
<br />
Another way to gain back static linking on Arch is to install {{AUR|cabal-static}} package. Unlike the official {{Pkg|cabal-install}}, this one does not pull dynamically linked {{ic|haskell-*}} dependencies from the official repositories and avoids mixing static and shared Haskell libraries installed on the same system. Then you can use Cabal as usual with the following limitation: '''you have to make sure''' that the only other Haskell packages you have installed are {{Pkg|ghc}}, {{Pkg|ghc-libs}} and {{Pkg|ghc-static}} (not {{Pkg|cabal-install}}, {{Pkg|stack}} and none of the {{ic|haskell-*}} packages available in the official repositories).<br />
<br />
==== stack-static ====<br />
<br />
Install {{AUR|stack-static}} package. Similarly to {{ic|cabal-static}} method, make sure that the only other Haskell packages you have installed from the official repositories are {{Pkg|ghc}}, {{Pkg|ghc-libs}} and {{Pkg|ghc-static}}. Then setup Stack to use system GHC as explained in [[#Configuring Stack for dynamic linking]]:<br />
<br />
$ stack setup --system-ghc --resolver ''resolver''<br />
<br />
To make these options permanent, paste the following snippet to {{ic|~/.stack/config.yaml}}:<br />
<br />
{{hc|~/.stack/config.yaml|<br />
# Stop downloading GHCs into isolated locations under ~/.stack.<br />
install-ghc: false<br />
<br />
# Allow Stack to pick the system GHC (false by default).<br />
system-ghc: true<br />
<br />
# Allow to use, say, Stackage snapshot for GHC 8.8.2 with system GHC 8.8.3.<br />
compiler-check: newer-minor<br />
}}<br />
<br />
This configuration will allow you to build statically linked packages as you would normally do, but using system GHC installation instead of GHC provided by Stack.<br />
<br />
==== hpack-static-bin ====<br />
<br />
{{AUR|hpack-static-bin}} provides a statically linked (meaning no haskell-* dependencies) alternative to {{Pkg|haskell-hpack}}. It is precompiled, so no make dependencies are needed.<br />
<br />
== See also ==<br />
<br />
*[http://learnyouahaskell.com/ Learn You a Haskell for Great Good!]<br />
*[http://book.realworldhaskell.org/ Real World Haskell]</div>Nedluddhttps://wiki.archlinux.org/index.php?title=Zsh&diff=375820Zsh2015-05-29T13:31:11Z<p>Nedludd: /* Prevent from putting duplicate lines in the history */ Fixing the english</p>
<hr />
<div>[[Category:Command shells]]<br />
[[cs:Zsh]]<br />
[[de:Zsh]]<br />
[[fr:Zsh]]<br />
[[ja:Zsh]]<br />
[[zh-CN:Zsh]]<br />
[http://zsh.sourceforge.net/Intro/intro_1.html Zsh] is a powerful shell that operates as both an interactive shell and as a scripting language interpreter. While being compatible with [[Bash]] (not by default, only if issuing {{ic|emulate sh}}), it offers many advantages such as:<br />
<br />
* Efficiency<br />
* Improved tab completion<br />
* Improved globbing<br />
* Improved array handling<br />
* Fully customisable<br />
<br />
The [http://zsh.sourceforge.net/FAQ/zshfaq01.html#l4 Zsh FAQ] offers more reasons to use Zsh.<br />
<br />
== Installation ==<br />
<br />
Before starting users may want to see what shell is currently being used:<br />
<br />
$ echo $SHELL<br />
<br />
[[pacman|Install]] the {{Pkg|zsh}} package available in the [[official repositories]]. For additional completion definitions, install the {{pkg|zsh-completions}} package as well.<br />
<br />
=== Initial configuration ===<br />
<br />
Make sure that Zsh has been installed correctly by running the following in a terminal:<br />
<br />
$ zsh<br />
<br />
You should now see '''zsh-newuser-install''', which will walk you through some basic configuration. If you want to skip this, press {{ic|q}}. If you did not see it, you can invoke it manually with<br />
<br />
$ zsh /usr/share/zsh/functions/Newuser/zsh-newuser-install -f<br />
<br />
=== Making Zsh your default shell ===<br />
<br />
{{Merge|Command-line_shell}}<br />
<br />
If the shell is listed in {{ic|/etc/shells}} you can use the {{ic|chsh}} command to change your default shell without root access. If you installed Zsh from the [[official repositories]], it should already have an entry in {{ic|/etc/shells}}.<br />
<br />
Change the default shell for the current user:<br />
<br />
$ chsh -s $(which zsh)<br />
<br />
{{Note|Please log out and log back in, in order to start using Zsh as the default shell.}}<br />
<br />
After logging back in, notice Zsh's prompt, which by default looks different from Bash's. Also verify that Zsh is the current shell by issuing:<br />
<br />
$ echo $SHELL<br />
<br />
{{Tip|If replacing {{Pkg|bash}}, users may want to move some code from {{ic|~/.bashrc}} to {{ic|~/.zshrc}} (e.g. the prompt and the [[Bash#Aliases|aliases]]) and from {{ic|~/.bash_profile}} to {{ic|~/.zprofile}} (e.g. [[Start X at Boot|the code that starts the X Window System]]).}}<br />
<br />
== Configuration files ==<br />
<br />
When starting Zsh, it'll source the following files in this order by default:<br />
;{{ic|/etc/zsh/zshenv}}:This file should contain commands to set the global [[#Configuring $PATH|command search path]] and other system-wide environment variables; it should not contain commands that produce output or assume the shell is attached to a tty.<br />
;{{ic|~/.zshenv}}:Similar to {{ic|/etc/zsh/zshenv}} but for per-user configuration. Generally used for setting some useful environment variables.<br />
;{{ic|/etc/zsh/zprofile}}:This is a global configuration file, it'll be sourced at login. Usually used for executing some general commands at login. Please note that on Arch Linux, by default it contains [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/zprofile?h=packages/zsh one line] which source the {{ic|/etc/profile}}, see [[#Global configuration files|below]] for details.<br />
;{{ic|/etc/profile}}:This file should be sourced by all Bourne-compatible shells upon login: it sets up an environment upon login and application-specific ({{ic|/etc/profile.d/*.sh}}) settings. Note that on Arch Linux, Zsh will also source this by default.<br />
;{{ic|~/.zprofile}}:This file is generally used for automatic execution of user's scripts at login.<br />
;{{ic|/etc/zsh/zshrc}}:Global configuration file, will be sourced when starting as a interactive shell.<br />
;{{ic|~/.zshrc}}:Main user configuration file, will be sourced when starting as a interactive shell.<br />
;{{ic|/etc/zsh/zlogin}}:A global configuration file, will be sourced at the ending of initial progress when starting as a login shell.<br />
;{{ic|~/.zlogin}}:Same as {{ic|/etc/zsh/zlogin}} but for per-user configuration.<br />
;{{ic|/etc/zsh/zlogout}}:A global configuration file, will be sourced when a login shell exits.<br />
;{{ic|~/.zlogout}}:Same as {{ic|/etc/zsh/zlogout}} but for per-user configuration.<br />
<br />
{{Note|<br />
* The paths used in Arch's {{Pkg|zsh}} package are different from the default ones used in the man pages.<br />
* {{ic|/etc/profile}} is not a part of the regular list of startup files run for Zsh, but is sourced from {{ic|/etc/zsh/zprofile}} in the {{Pkg|zsh}} package. Users should take note that {{ic|/etc/profile}} sets the {{ic|$PATH}} variable which will overwrite any {{ic|$PATH}} variable set in {{ic|~/.zshenv}}. To prevent this, please set the {{ic|$PATH}} variable in {{ic|~/.zshrc}}. (It's not recommended to replace the default [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/zprofile?h&#61;packages/zsh one line] in {{ic|/etc/zsh/zprofile}} with something other, it'll break the integrality of other packages which provide some scripts in {{ic|/etc/profile.d}})<br />
}}<br />
<br />
=== Global configuration files ===<br />
<br />
Occasionally users might want to have some settings applied globally to all Zsh users. The zsh(1) said that there are some global configuration files, for example {{ic|/etc/zshrc}}. This however is slightly different on Arch, since it has been compiled with flags specifically to target[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/zsh#n34] {{ic|/etc/zsh/}} instead.<br />
<br />
So, for global configuration use {{ic|/etc/zsh/zshrc}}, not {{ic|/etc/zshrc}}. The same goes for {{ic|/etc/zsh/zshenv}}, {{ic|/etc/zsh/zlogin}} and {{ic|/etc/zsh/zlogout}}. Note that these files are not installed by default, so create them if desired.<br />
<br />
The only exception is zprofile, use {{ic|/etc/profile}} instead.<br />
<br />
== Configure Zsh ==<br />
<br />
Although Zsh is usable out of the box, it is almost certainly not set up the way most users would like to use it, but due to the sheer amount of customization available in Zsh, configuring Zsh can be a daunting and time-consuming experience.<br />
<br />
=== Simple .zshrc ===<br />
<br />
Included below is a sample configuration file, it provides a decent set of default options as well as giving examples of many ways that Zsh can be customized. In order to use this configuration save it as a file named {{ic|.zshrc}}. Apply the changes without needing to logout and then back in by running:<br />
<br />
$ source ~/.zshrc<br />
<br />
Here is a simple {{ic|.zshrc}}:<br />
<br />
{{hc|~/.zshrc|<br />
autoload -U compinit promptinit<br />
compinit<br />
promptinit<br />
<br />
# This will set the default prompt to the walters theme<br />
prompt walters}}<br />
<br />
=== Configuring $PATH ===<br />
<br />
Information about setting up the system path per user in zsh can be found here: http://zsh.sourceforge.net/Guide/zshguide02.html#l24<br />
<br />
In short, put the following in {{ic|~/.zshenv}}:<br />
{{hc|~/.zshenv|<br />
typeset -U path<br />
path&#61;(~/bin /other/things/in/path $path)}}<br />
<br />
See also the note in [[Zsh#Configuration_files]].<br />
<br />
=== Command completion ===<br />
<br />
Perhaps the most compelling feature of Zsh is its advanced autocompletion abilities. At the very least, enable autocompletion in {{ic|.zshrc}}. To enable autocompletion, add the following to your {{ic|~/.zshrc}}:<br />
<br />
{{hc|~/.zshrc|<br />
autoload -U compinit<br />
compinit<br />
}}<br />
<br />
The above configuration includes ssh/scp/sftp hostnames completion but in order for this feature to work, users need to prevent ssh from hashing hosts names in {{ic|~/.ssh/known_hosts}}.<br />
{{Warning|This makes the computer vulnerable to [http://blog.rootshell.be/2010/11/03/bruteforcing-ssh-known_hosts-files/ "Island-hopping" attacks]. In that intention, comment the following line or set the value to {{ıc|no}}:<br />
{{hc|/etc/ssh/ssh_config|<br />
#HashKnownHosts yes}}<br />
And move {{ic|~/.ssh/known_hosts}} somewhere else so that ssh creates a new one with un-hashed hostnames (previously known hosts will thus be lost). For more information, see the SSH readme for [http://nms.lcs.mit.edu/projects/ssh/README.hashed-hosts hashed-hosts].<br />
}}<br />
<br />
For autocompletion with an arrow-key driven interface, add the following to:<br />
{{hc|~/.zshrc|<br />
zstyle ':completion:*' menu select}}<br />
:''To activate the menu, press tab twice.''<br />
<br />
For autocompletion of command line switches for aliases, add the following to:<br />
{{hc|~/.zshrc|<br />
setopt completealiases}}<br />
<br />
=== The "command not found" hook ===<br />
<br />
See [[Pkgfile#Command not found]].<br />
<br />
=== Preventing duplicate lines in the history ===<br />
<br />
It is very convinient to ignore duplicate lines in the history. To do so, put the following:<br />
{{hc|~/.zshrc|<br />
setopt HIST_IGNORE_DUPS}}<br />
<br />
=== Key bindings ===<br />
<br />
Zsh does not use readline, instead it uses its own and more powerful zle. It does not read {{ic|/etc/inputrc}} or {{ic|~/.inputrc}}.<br />
Zle has an [[emacs]] mode and a [[vi]] mode. By default, it tries to guess whether emacs or vi keys from the {{ic|$EDITOR}} environment variable are desired. If it is empty, it will default to emacs. Change this with {{ic|bindkey -v}} or {{ic|bindkey -e}}.<br />
<br />
To get some special keys working:<br />
{{hc|~/.zshrc|2=<br />
# create a zkbd compatible hash;<br />
# to add other keys to this hash, see: man 5 terminfo<br />
typeset -A key<br />
<br />
key[Home]=${terminfo[khome]}<br />
<br />
key[End]=${terminfo[kend]}<br />
key[Insert]=${terminfo[kich1]}<br />
key[Delete]=${terminfo[kdch1]}<br />
key[Up]=${terminfo[kcuu1]}<br />
key[Down]=${terminfo[kcud1]}<br />
key[Left]=${terminfo[kcub1]}<br />
key[Right]=${terminfo[kcuf1]}<br />
key[PageUp]=${terminfo[kpp]}<br />
key[PageDown]=${terminfo[knp]}<br />
<br />
# setup key accordingly<br />
[[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line<br />
[[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line<br />
[[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode<br />
[[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char<br />
[[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history<br />
[[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history<br />
[[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char<br />
[[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char<br />
[[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" beginning-of-buffer-or-history<br />
[[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" end-of-buffer-or-history<br />
<br />
# Finally, make sure the terminal is in application mode, when zle is<br />
# active. Only then are the values from $terminfo valid.<br />
if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then<br />
function zle-line-init () {<br />
printf '%s' "${terminfo[smkx]}"<br />
}<br />
function zle-line-finish () {<br />
printf '%s' "${terminfo[rmkx]}"<br />
}<br />
zle -N zle-line-init<br />
zle -N zle-line-finish<br />
fi<br />
}}<br />
<br />
{{Note|To get the proper sequences for certain key combinations, start {{ic|cat}} or {{ic|read}} without any parameters and press them; they should then be printed in the terminal. Both can be closed again via {{ic|Ctrl+c}}.}}<br />
<br />
==== Alternative method without using terminfo ====<br />
<br />
Run {{ic|autoload zkbd}} followed by just {{ic|zkbd}}. If users cannot press the key it asks for (e.g. {{ic|F11}} maximizes the window), press space to skip it. After finishing with zkbd, add the following to {{ic|~/.zshrc}}:<br />
<br />
{{hc|~/.zshrc|autoload zkbd<br />
source ~/.zkbd/$TERM-:0.0 # may be different - check where zkbd saved the configuration:<br />
<br />
[[ -n ${key[Backspace]} ]] && bindkey "${key[Backspace]}" backward-delete-char<br />
[[ -n ${key[Insert]} ]] && bindkey "${key[Insert]}" overwrite-mode<br />
[[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line<br />
[[ -n ${key[PageUp]} ]] && bindkey "${key[PageUp]}" up-line-or-history<br />
[[ -n ${key[Delete]} ]] && bindkey "${key[Delete]}" delete-char<br />
[[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line<br />
[[ -n ${key[PageDown]} ]] && bindkey "${key[PageDown]}" down-line-or-history<br />
[[ -n ${key[Up]} ]] && bindkey "${key[Up]}" up-line-or-search<br />
[[ -n ${key[Left]} ]] && bindkey "${key[Left]}" backward-char<br />
[[ -n ${key[Down]} ]] && bindkey "${key[Down]}" down-line-or-search<br />
[[ -n ${key[Right]} ]] && bindkey "${key[Right]}" forward-char<br />
}}<br />
<br />
==== Bind key to ncurses application ====<br />
<br />
Bind a ncurses application to a keystoke, but it will not accept interaction. Use {{ic|BUFFER}} variable to make it work. The following example lets users open ncmpcpp using {{ic|Alt+\}}:<br />
{{hc|~/.zshrc|2=<br />
ncmpcppShow() { BUFFER="ncmpcpp"; zle accept-line; }<br />
zle -N ncmpcppShow<br />
bindkey '^[\' ncmpcppShow<br />
}}<br />
<br />
==== Alternate way to bind ncurses application ====<br />
<br />
This method will keep everything you entered in the line before calling application<br />
{{hc|~/.zshrc|2=<br />
ncmpcppShow() { ncmpcpp <$TTY; zle redisplay; }<br />
zle -N ncmpcppShow<br />
bindkey '^[\' ncmpcppShow<br />
}}<br />
<br />
==== File manager key binds ====<br />
<br />
Key binds like those used in graphic file managers may come handy. The first comes back in directory hostory ({{ic|Alt+Left}}), the second let the user go to the parent directory ({{ic|Alt+Up}}). They also display the directory content.<br />
<br />
{{hc|~/.zshrc|<nowiki><br />
cdUndoKey() {<br />
popd > /dev/null<br />
zle reset-prompt<br />
echo<br />
ls<br />
echo<br />
}<br />
<br />
cdParentKey() {<br />
pushd .. > /dev/null<br />
zle reset-prompt<br />
echo<br />
ls<br />
echo<br />
}<br />
<br />
zle -N cdParentKey<br />
zle -N cdUndoKey<br />
bindkey '^[[1;3A' cdParentKey<br />
bindkey '^[[1;3D' cdUndoKey<br />
</nowiki>}}<br />
<br />
=== History search ===<br />
<br />
Add these lines to .zshrc<br />
<br />
{{hc|~/.zshrc|<nowiki><br />
[[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" history-beginning-search-backward<br />
[[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" history-beginning-search-forward<br />
</nowiki>}}<br />
<br />
Doing this, only past commands beginning with the current input would have been shown.<br />
<br />
=== Prompts ===<br />
<br />
There is a quick and easy way to set up a colored prompt in Zsh. Make sure that prompt is set to autoload in {{ic|.zshrc}}. This can be done by adding these lines to:<br />
<br />
{{hc|~/.zshrc|<br />
autoload -U promptinit<br />
promptinit<br />
}}<br />
<br />
Available prompts are listed by running the command:<br />
<br />
$ prompt -l<br />
<br />
For example, to use the prompt {{ic|walters}}, enter:<br />
<br />
$ prompt walters<br />
<br />
To preview all available themes, use this command:<br />
<br />
$ prompt -p<br />
<br />
=== Customizing the prompt ===<br />
<br />
For users who are dissatisfied with the prompts mentioned above (or want to expand their usefulness), Zsh offers the possibility to build a custom prompt. Zsh supports a left- and right-sided prompt additional to the single, left-sided prompt that is common to all shells. Customize it by using {{ic|1=PROMPT=}} with the following variables:<br />
<br />
See [http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html Prompt Expansion] for a list of prompt variables and conditional substrings.<br />
<br />
==== Colors ====<br />
<br />
Zsh sets colors differently than [[Color_Bash_Prompt|Bash]]. Add {{ic|autoload -U colors && colors}} before {{ic|1=PROMPT=}} in {{ic|.zshrc}} to use them. Usually you will want to put these inside {{ic|%{ [...] %} }} so the cursor does not move.<br />
<br />
{{ic|$fg[color]}} will set the text color (red, green, blue, etc. - defaults to whatever format set prior to text)<br />
<br />
{| class="wikitable"<br />
! Command || Description<br />
|-<br />
| {{ic|%F{color} [...] %f}} || effectively the same as the previous, but with less typing. Can also prefix F with a number instead.<br />
|-<br />
| {{ic|$fg_no_bold[color]}}|| will set text to non-bold and set the text color<br />
|-<br />
| {{ic|$fg_bold[color]}}|| will set the text to bold and set the text color<br />
|-<br />
| {{ic|$reset_color}}|| will reset the text color to the default color. Does not reset bold. use {{ic|%b}} to reset bold. Saves typing if it's just {{ic|%f}} though. ||<br />
|-<br />
| {{ic|%K{color} [...] %k}} || will set the background color. Same color as non-bold text color. Prefixing with any single-digit number makes the bg black.<br />
|}<br />
<br />
{| class="wikitable"<br />
|-<br />
! colspan="2" | Possible color values<br />
|-<br />
| {{ic|black}} or {{ic|0}} || {{ic|red}} or {{ic|1}}<br />
|-<br />
| {{ic|green}} or {{ic|2}} || {{ic|yellow}} or {{ic|3}}<br />
|-<br />
| {{ic|blue}} or {{ic|4}} || {{ic|magenta}} or {{ic|5}}<br />
|-<br />
| {{ic|cyan}} or {{ic|6}} || {{ic|white}} or {{ic|7}}<br />
|}<br />
<br />
{{Note| Bold text does not necessarily use the same colors as normal text. For example, {{ic|$fg['yellow']}} looks brown or a very dark yellow, while {{ic|$fg_no_bold['yellow']}} looks like bright or regular yellow.}}<br />
<br />
==== Example ====<br />
<br />
This is an example of a two-sided prompt:<br />
<br />
PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg_no_bold[yellow]%}%1~ %{$reset_color%}%#"<br />
RPROMPT="[%{$fg_no_bold[yellow]%}%?%{$reset_color%}]"<br />
<br />
And here's how it will be displayed:<br />
<br />
username@host ~ % [0]<br />
<br />
=== Dirstack ===<br />
<br />
Zsh can be configured to remember the DIRSTACKSIZE last visited folders. This can then be used to ''cd'' them very quickly. You need to add some lines to you configuration file:<br />
<br />
{{hc|.zshrc|<nowiki><br />
DIRSTACKFILE="$HOME/.cache/zsh/dirs"<br />
if [[ -f $DIRSTACKFILE ]] && [[ $#dirstack -eq 0 ]]; then<br />
dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )<br />
[[ -d $dirstack[1] ]] && cd $dirstack[1]<br />
fi<br />
chpwd() {<br />
print -l $PWD ${(u)dirstack} >$DIRSTACKFILE<br />
}<br />
<br />
DIRSTACKSIZE=20<br />
<br />
setopt autopushd pushdsilent pushdtohome<br />
<br />
## Remove duplicate entries<br />
setopt pushdignoredups<br />
<br />
## This reverts the +/- operators.<br />
setopt pushdminus<br />
</nowiki>}}<br />
<br />
Now use<br />
dirs -v<br />
to print the dirstack. Use {{ic|cd -<NUM>}} to go back to a visited folder. Use autocompletion after the dash. This proves very handy if using the autocompletion menu.<br />
<br />
=== Help command ===<br />
Unlike [[bash]], ''zsh'' does not enable a built in {{ic|help}} command. To use {{ic|help}} in zsh, add following to your {{ic|zshrc}}:<br />
<br />
{{bc|1=<br />
autoload -U run-help<br />
autoload run-help-git<br />
autoload run-help-svn<br />
autoload run-help-svk<br />
unalias run-help<br />
alias help=run-help<br />
}}<br />
<br />
=== Fish-like syntax highlighting ===<br />
<br />
[[Fish]] provides a very powerful shell syntax highlighting. To use this in zsh, you can install {{pkg|zsh-syntax-highlighting}} from offical repository and add following to your zshrc:<br />
{{bc|<br />
source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh<br />
}}<br />
<br />
=== Sample .zshrc files ===<br />
<br />
* A package in offical repository named {{Pkg|grml-zsh-config}} comes from http://grml.org/zsh and provides a zshrc file that includes many tweaks for Zshell. This is the default configuration for the [https://www.archlinux.org/download/ monthly ISO releases].<br />
* Basic setup, with dynamic prompt and window title/hardinfo => http://github.com/MrElendig/dotfiles-alice/blob/master/.zshrc;<br />
* https://github.com/slashbeast/things/blob/master/configs/DOTzshrc - zshrc with multiple features, be sure to check out comments into it. Notable features: confirm function to ensure that user want to run poweroff, reboot or hibernate, support for GIT in prompt (done without vcsinfo), tab completion with menu, printing current executed command into window's title bar and more.<br />
<br />
=== Configuration Frameworks ===<br />
<br />
* [https://github.com/robbyrussell/oh-my-zsh oh-my-zsh] is a popular, community-driven framework for managing your Zsh configuration. It comes bundled with a ton of helpful functions, helpers, plugins, themes.<br />
* [https://github.com/sorin-ionescu/prezto Prezto - Instantly Awesome Zsh] (available in AUR as {{AUR|prezto-git}}) is a configuration framework for Zsh. It comes with modules, enriching the command line interface environment with sane defaults, aliases, functions, auto completion, and prompt themes.<br />
* [https://github.com/zsh-users/antigen Antigen] (available in AUR as {{AUR|antigen-git}}) - A plugin manager for zsh, inspired by oh-my-zsh and vundle.<br />
<br />
=== Autostarting applications ===<br />
<br />
{{note|{{ic|$ZDOTDIR}} defaults to {{ic|$HOME}}}}<br />
<br />
Zsh always executes {{ic|/etc/zsh/zshenv}} and {{ic|$ZDOTDIR/.zshenv}} so do not bloat these files.<br />
<br />
If the shell is a login shell, commands are read from {{ic|/etc/profile}} and then {{ic|$ZDOTDIR/.zprofile}}. Then, if the shell is interactive, commands are read from {{ic|/etc/zsh/zshrc}} and then {{ic|$ZDOTDIR/.zshrc}}. Finally, if the shell is a login shell, {{ic|/etc/zsh/zlogin}} and {{ic|$ZDOTDIR/.zlogin}} are read.<br />
<br />
See also the ''STARTUP/SHUTDOWN FILES'' section of {{ic|man zsh}}.<br />
<br />
=== Persistent rehash ===<br />
<br />
Typically, compinit will not automatically find new executables in the $PATH. For example, after you install a new package, the files in /usr/bin would not be immediately or automatically included in the completion. Thus, to have these new exectuables included, one would run:<br />
$ rehash<br />
<br />
<br />
This 'rehash' can be set to happen automatically. Simply include the following in your {{ic|zshrc}}:<br />
setopt nohashdirs<br />
If it doesn't work, add following [http://www.zsh.org/mla/users/2001/msg00037.html]:<br />
setopt nohashcmds<br />
<br />
== Uninstallation ==<br />
<br />
Change the default shell before removing the {{Pkg|zsh}} package.<br />
<br />
{{Warning|Failure to follow the below procedure may result in users no longer having access to a working shell.}}<br />
<br />
Run following command:<br />
<br />
$ chsh -s /bin/bash ''user''<br />
<br />
Use it for every user with ''zsh'' set as their login shell (including root if needed). When completed, the {{Pkg|zsh}} package can be removed.<br />
<br />
Alternatively, change the default shell back to Bash by editing {{ic|/etc/passwd}} as root.<br />
<br />
{{Warning|It is strongly recommended to use {{ic|vipw}} when editing {{ic|/etc/passwd}} as it helps prevent invalid entries and/or syntax errors.}}<br />
<br />
For example, change the following:<br />
<br />
''username'':x:1000:1000:''Full Name'',,,:/home/''username'':/bin/zsh<br />
<br />
To this:<br />
<br />
''username'':x:1000:1000:''Full Name'',,,:/home/''username'':/bin/bash<br />
<br />
== See also ==<br />
<br />
*[http://zsh.sourceforge.net/Guide/zshguide.html A User's Guide to ZSH]<br />
*[http://zsh.sourceforge.net/Doc/Release/index-frame.html The Z Shell Manual] (different format available [http://zsh.sourceforge.net/Doc/ here])<br />
*[http://zsh.sourceforge.net/FAQ/zshfaq01.html Zsh FAQ]<br />
*[http://grml.org/zsh/zsh-lovers.html zsh-lovers(1)] (this is also available as {{pkg|zsh-lovers}} in offical repository)<br />
*[http://zshwiki.org/home/ Zsh Wiki]<br />
*[https://wiki.gentoo.org/wiki/Zsh/HOWTO Gentoo Wiki: Zsh/HOWTO]<br />
*[http://www.bash2zsh.com/zsh_refcard/refcard.pdf Bash2Zsh Reference Card]</div>Nedluddhttps://wiki.archlinux.org/index.php?title=ZNC&diff=242983ZNC2013-01-04T20:40:21Z<p>Nedludd: Spelling</p>
<hr />
<div>[[Category:Internet Relay Chat]]<br />
'''ZNC''' is an advanced IRC bouncer that is left connected so an IRC client can disconnect/reconnect without losing the chat session.<br />
<br />
== Installation ==<br />
1. Install {{pkg|znc}} from the [[Official Repositories]]. The installation script will create a group and user '''znc'''. The default home directory for this user is {{ic|/var/lib/znc}}.<br />
<br />
{{Note| A bug in znc.install (znc 1.0-2) sets the znc user's home directory as {{ic|/var/empty}}. {{ic|/var/lib/znc}} is still created and owned by the correct user/group. You should change znc's home directory to {{ic|/var/lib/znc}}}}<br />
<br />
2. Generate ZNC config as user '''znc'''.<br />
# su - znc<br />
$ znc --makeconf<br />
Go through the wizard and setup your preferences.<br />
{{warning|Do not edit configuration files manually in a text editor while ZNC is running. There is a very good chance you will lose your configuration. Use the webadmin or controlpanel modules to change settings on-the-fly. They are both included in the package.}}<br />
<br />
3. To make ZNC start on boot:<br />
# systemctl enable znc<br />
<br />
Start and stop the ZNC daemon as usual by running:<br />
<br />
# systemctl {start|stop|restart} znc<br />
<br />
== Configuration ==<br />
Though you can choose to modify your configuration files manually, this requires shutting down the server first. '''Do not edit configuration files while ZNC is running'''.<br />
<br />
=== Webadmin Module ===<br />
If you enabled the web admin module, you can access it at {{ic|http://''yourhostname'':''znc port''}}, the znc port number is the same as you defined for connecting to the bouncer.<br />
<br />
=== Control Panel Module ===<br />
If you enabled the control panel module, {{ic|/msg *controlpanel help}} for a list of settings while you are connected to the server.<br />
<br />
== See also ==<br />
* [http://wiki.znc.in/ZNC ZNC's website]</div>Nedluddhttps://wiki.archlinux.org/index.php?title=64-bit_FAQ&diff=7095964-bit FAQ2009-06-22T15:04:45Z<p>Nedludd: /* Will I have all the packages from my 32-bit Arch I am used to? */</p>
<hr />
<div>[[Category:Arch64 (English)]]<br />
[[Category:FAQs (English)]]<br />
<br />
{{i18n_links_start}}<br />
{{i18n_entry|Česky|Arch64 FAQ (Česky)}}<br />
{{i18n_entry|English|Arch64 FAQ}}<br />
{{i18n_entry|Español|Arch64 FAQ (Español)}}<br />
{{i18n_entry|Ελληνικά|Arch64 FAQ (Ελληνικά)}}<br />
{{i18n_entry|Français|Arch64 FAQ (Français)}}<br />
{{i18n_entry|Italiano|Arch64 FAQ (Italiano)}}<br />
{{i18n_entry|简体中文|Arch64问答_(简体中文)}}<br />
{{i18n_entry|Русский|Arch64 FAQ (Русский)}}<br />
{{i18n_links_end}}<br />
<br />
Below is a list of frequently asked questions about Arch64.<br />
<br />
==How can I install Arch64?==<br />
Just use our [http://www.archlinux.org/download/ official install ISO CD].<br />
<br />
==How complete is the port?==<br />
The port is ready for daily use in a desktop or server environment.<br />
<br />
==Will I have all the packages from my 32-bit Arch I am used to?==<br />
The Core and Extra repositories are ported and almost everything is up to date. At most, the x86_64 versions are only hours or a few days behind the i686 ones.<br />
<br />
Occasionally, a package in AUR will only have 'i686' listed, but often they work for 64-bit too, just try adding 'x86_64'.<br />
<br />
==Does 64-bit mean a great speed improvement?==<br />
For applications using the 64-bit CPU registers (large databases and such) this is true in most cases. Some multimedia applications will also run noticeably faster. If you know an application which is known to be much faster when using SSE3 extensions you can rebuild the package yourself. We ''only'' compile with SSE2 support (from march=x86_64) and -O2 optimizations.<br />
For more read http://forums.gentoo.org/viewtopic.php?t=221045 or http://www.thejemreport.com/mambo/content/view/74/74/ .<br />
<br />
For the rest of the system: It doesn't make any difference if the keyboard waits. <br />
<br />
For further details watch our [[Arch64_ToDoS]]. There you will find a list comparing arch32/arch64 package versions.<br />
<br />
For certain boot problems try these special kernel boot flags: http://www.x86-64.org/lists/discuss/msg03747.html (dead link)<br />
<br />
I have three 64-bit Archies running now, and they perform noticeably better under heavy load. It just seems to deliver more punch.<br />
<br />
==How can I file bugs?==<br />
Simply use Arch's flyspray but select x86_64 in the Architecture field if you think it's a port-related problem!<br />
<br />
==What repos should I set up for pacman to use?==<br />
All repos are supported for the port.<br />
<br />
==How can I patch existing PKGBUILDs for use with Arch64?==<br />
We add to all ported packages this variable:<br />
arch=('i686' 'x86_64') <br />
Add small patches directly to the sources and md5sums area but use for complete different sources:<br />
[ "$CARCH" = "x86_64" ] && source=(${source[@]} 'other source')<br />
[ "$CARCH" = "x86_64" ] && md5sums=(${md5sums[@]} 'other md5sum')<br />
For any small fix use this in the build area:<br />
[ "$CARCH" = "x86_64" ] && (patch -Np0 -i ../foo_x86_64.patch || return 1)<br />
Or when you need more changes:<br />
if [ "$CARCH" = "x86_64" ]; then<br />
configure/patch/sed # for x86_64<br />
else configure/patch/sed # for i686<br />
fi<br />
<br />
==What will I miss in Arch64?==<br />
Nothing, really. Almost all applications support 64-bit by now or are in the transition to become 64-bit compatible.<br />
<br />
These applications were previously problematic, but are now available in the [[AUR]] and work fine:<br />
* Skype as bin32-skype<br />
* Wine as bin32-wine<br />
* Zsnes as bin32-zsnes<br />
<br />
The biggest problem are packages that are either <strong>closed source</strong> or contains x86-specific assembly that is cumbersome to port to 64-bit (typical for emulators).<br />
<br />
* TeamSpeak will not support 64-bit until the next version is released.<br />
* Acrobat Reader plugin is not available in 64-bit, but you can run the 32-bit version in compatibility mode<br />
<br />
Everything else should work perfectly fine. If you miss any Arch32 package in our port and you know that it will compile on x86_64 (perhaps you have found it as native packages in another 64-bit distribution), just contact the devs or request a new package in the forums.<br />
<br />
==Can I build 32-bit packages for i686 inside Arch64?==<br />
<br />
Yes. You need a working i686 chroot (installation with i686 iso "quickinstall" is recommended for the quick way to install it inside Arch64 or see [[Arch64 Install bundled 32bit system]]). Install "linux32" wrapper pkg from current to make the chroot behave like a real i686 system. Then use this script to login into the chroot environment as root:<br />
<br />
#!/bin/bash<br />
mount --bind /dev /path-to-your-chroot/dev<br />
mount --bind /dev/pts /path-to-your-chroot/dev/pts<br />
mount --bind /dev/shm /path-to-your-chroot/dev/shm<br />
mount -t proc none /path-to-your-chroot/proc<br />
mount -t sysfs none /path-to-your-chroot/sys<br />
linux32 chroot /path-to-your-chroot<br />
<br />
If you keep the sources on the x86_64 host system you can add<br />
"mount --bind /path-to-your-stored-sources /path-to-your-chroot/path-to-your-stored-sources" <br />
to share sources from host to chroot system for pkg building used in /etc/makepkg.conf.<br />
<br />
==Can I run 32-bit apps inside Arch64?==<br />
Yes! <br />
<br />
# You can install lib32-* libs from comunity repository for a Multilib system.<br />
# Or you can create another chroot with 32bit system:<br />
<br />
Boot into Arch64, startx, open a term.<br />
$ xhost +local:<br />
$ su<br />
# mount /dev/sda1 /mnt/arch32<br />
# mount --bind /proc /mnt/arch32/proc<br />
# chroot /mnt/arch32<br />
# su your32bitusername<br />
$ /usr/bin/command-you want # or eg: /opt/mozilla/bin/firefox<br />
<br />
Some 32-bit apps (like OpenOffice) may require additional bindings. The following lines can be placed in rc.local to ensure you get all you need for the 32-bit apps (assuming /mnt/arch32 is mounted in fstab):<br />
mount --bind /dev /mnt/arch32/dev<br />
mount --bind /dev/pts /mnt/arch32/dev/pts<br />
mount --bind /dev/shm /mnt/arch32/dev/shm<br />
mount --bind /proc /mnt/arch32/proc<br />
mount --bind /proc/bus/usb /mnt/arch32/proc/bus/usb<br />
mount --bind /sys /mnt/arch32/sys<br />
mount --bind /tmp /mnt/arch32/tmp<br />
#comment the following line if you do not use the same home folder<br />
mount --bind /home /mnt/arch32/home<br />
You can then type in a term:<br />
$ xhost +localhost<br />
$ sudo chroot /mnt/arch32 su your32bitusername /opt/openoffice/program/soffice<br />
<br />
==Can I upgrade/switch my system from i686 to x86_64 without reinstalling?==<br />
No. However, you can start the system with the Arch64 install CD, mount the disk, backup anything you may want to keep that isn't a 32-bit binary (e.g: /home & /etc), and install.</div>Nedluddhttps://wiki.archlinux.org/index.php?title=Dropbox&diff=49345Dropbox2008-09-12T20:13:36Z<p>Nedludd: </p>
<hr />
<div>[[Category:HOWTOs]]<br />
<br />
[http://getdropbox.com Dropbox] is a file sharing system that recently introduced a Linux client. Use it to transparently sync files across computers and architectures. Simply drop files into your "~/Dropbox" folder, and they will automatically sync to your centralized repository.<br />
<br />
==Installation==<br />
<br />
The Linux Dropbox client is packaged as a Nautilus plugin. It is in the [[AUR]] as "nautilus-dropbox". <br />
<br />
#Simply run "yaourt nautilus-dropbox" to build and install. (See [http://archux.com/page/installing-programs-aur here] for instructions on installing from the AUR).<br />
#Now restart Nautilus. You will see the Dropbox icon in your panel.<br />
#Eventually a popup will ask you to login to your Dropbox account, or start a new one. Enter your credentials.<br />
#After some time you will see a "Welcome to Dropbox" popup, which will give you the opportunity to view a short tour of Dropbox.<br />
#Press the "Finish and go to My Dropbox".<br />
<br />
To use it, simply drag and drop files into your "Dropbox" folder.<br />
<br />
==Without Nautilus==<br />
<br />
If you use KDE or other non-Gnome desktop environment, you may not want to use Nautilus. Here's how to do that. Unfortunately until someone comes up with a way to bypass this, you will have to use Nautilus for the set-up. Once Dropbox is installed, you can safely remove Nautilus.<br />
<br />
#Install Dropbox using Nautilus with the instructions above. If you start Nautilus with the "--no-desktop" option it won't take over your environment.<br />
#Stop Nautilus by doing "killall nautilus".<br />
#There will be three directories in your home directory called: ".dropbox-dist", ".dropbox", and "Dropbox".<br />
#You will see a daemon running called "dropboxd" running out of the ".dropbox-dist" directory. Use this to start and stop Dropbox. You can put "~/.dropbox-dist/dropboxd" in your startup scripts if you wish.<br />
#Move files into "Dropbox" to sync them.<br />
#".dropbox" holds configuration databases and caches for Dropbox. Don't touch this.<br />
<br />
Enjoy!</div>Nedluddhttps://wiki.archlinux.org/index.php?title=Dropbox&diff=49344Dropbox2008-09-12T20:12:54Z<p>Nedludd: Change category</p>
<hr />
<div>[[Category:Howtos]]<br />
<br />
[http://getdropbox.com Dropbox] is a file sharing system that recently introduced a Linux client. Use it to transparently sync files across computers and architectures. Simply drop files into your "~/Dropbox" folder, and they will automatically sync to your centralized repository.<br />
<br />
==Installation==<br />
<br />
The Linux Dropbox client is packaged as a Nautilus plugin. It is in the [[AUR]] as "nautilus-dropbox". <br />
<br />
#Simply run "yaourt nautilus-dropbox" to build and install. (See [http://archux.com/page/installing-programs-aur here] for instructions on installing from the AUR).<br />
#Now restart Nautilus. You will see the Dropbox icon in your panel.<br />
#Eventually a popup will ask you to login to your Dropbox account, or start a new one. Enter your credentials.<br />
#After some time you will see a "Welcome to Dropbox" popup, which will give you the opportunity to view a short tour of Dropbox.<br />
#Press the "Finish and go to My Dropbox".<br />
<br />
To use it, simply drag and drop files into your "Dropbox" folder.<br />
<br />
==Without Nautilus==<br />
<br />
If you use KDE or other non-Gnome desktop environment, you may not want to use Nautilus. Here's how to do that. Unfortunately until someone comes up with a way to bypass this, you will have to use Nautilus for the set-up. Once Dropbox is installed, you can safely remove Nautilus.<br />
<br />
#Install Dropbox using Nautilus with the instructions above. If you start Nautilus with the "--no-desktop" option it won't take over your environment.<br />
#Stop Nautilus by doing "killall nautilus".<br />
#There will be three directories in your home directory called: ".dropbox-dist", ".dropbox", and "Dropbox".<br />
#You will see a daemon running called "dropboxd" running out of the ".dropbox-dist" directory. Use this to start and stop Dropbox. You can put "~/.dropbox-dist/dropboxd" in your startup scripts if you wish.<br />
#Move files into "Dropbox" to sync them.<br />
#".dropbox" holds configuration databases and caches for Dropbox. Don't touch this.<br />
<br />
Enjoy!</div>Nedluddhttps://wiki.archlinux.org/index.php?title=Dropbox&diff=49343Dropbox2008-09-12T20:09:45Z<p>Nedludd: </p>
<hr />
<div>[[Category:howto]]<br />
<br />
[http://getdropbox.com Dropbox] is a file sharing system that recently introduced a Linux client. Use it to transparently sync files across computers and architectures. Simply drop files into your "~/Dropbox" folder, and they will automatically sync to your centralized repository.<br />
<br />
==Installation==<br />
<br />
The Linux Dropbox client is packaged as a Nautilus plugin. It is in the [[AUR]] as "nautilus-dropbox". <br />
<br />
#Simply run "yaourt nautilus-dropbox" to build and install. (See [http://archux.com/page/installing-programs-aur here] for instructions on installing from the AUR).<br />
#Now restart Nautilus. You will see the Dropbox icon in your panel.<br />
#Eventually a popup will ask you to login to your Dropbox account, or start a new one. Enter your credentials.<br />
#After some time you will see a "Welcome to Dropbox" popup, which will give you the opportunity to view a short tour of Dropbox.<br />
#Press the "Finish and go to My Dropbox".<br />
<br />
To use it, simply drag and drop files into your "Dropbox" folder.<br />
<br />
==Without Nautilus==<br />
<br />
If you use KDE or other non-Gnome desktop environment, you may not want to use Nautilus. Here's how to do that. Unfortunately until someone comes up with a way to bypass this, you will have to use Nautilus for the set-up. Once Dropbox is installed, you can safely remove Nautilus.<br />
<br />
#Install Dropbox using Nautilus with the instructions above. If you start Nautilus with the "--no-desktop" option it won't take over your environment.<br />
#Stop Nautilus by doing "killall nautilus".<br />
#There will be three directories in your home directory called: ".dropbox-dist", ".dropbox", and "Dropbox".<br />
#You will see a daemon running called "dropboxd" running out of the ".dropbox-dist" directory. Use this to start and stop Dropbox. You can put "~/.dropbox-dist/dropboxd" in your startup scripts if you wish.<br />
#Move files into "Dropbox" to sync them.<br />
#".dropbox" holds configuration databases and caches for Dropbox. Don't touch this.<br />
<br />
Enjoy!</div>Nedluddhttps://wiki.archlinux.org/index.php?title=Dropbox&diff=49342Dropbox2008-09-12T20:09:28Z<p>Nedludd: New page: Category:howto =Dropbox= [http://getdropbox.com Dropbox] is a file sharing system that recently introduced a Linux client. Use it to transparently sync files across computers and ar...</p>
<hr />
<div>[[Category:howto]]<br />
<br />
=Dropbox=<br />
<br />
[http://getdropbox.com Dropbox] is a file sharing system that recently introduced a Linux client. Use it to transparently sync files across computers and architectures. Simply drop files into your "~/Dropbox" folder, and they will automatically sync to your centralized repository.<br />
<br />
==Installation==<br />
<br />
The Linux Dropbox client is packaged as a Nautilus plugin. It is in the [[AUR]] as "nautilus-dropbox". <br />
<br />
#Simply run "yaourt nautilus-dropbox" to build and install. (See [http://archux.com/page/installing-programs-aur here] for instructions on installing from the AUR).<br />
#Now restart Nautilus. You will see the Dropbox icon in your panel.<br />
#Eventually a popup will ask you to login to your Dropbox account, or start a new one. Enter your credentials.<br />
#After some time you will see a "Welcome to Dropbox" popup, which will give you the opportunity to view a short tour of Dropbox.<br />
#Press the "Finish and go to My Dropbox".<br />
<br />
To use it, simply drag and drop files into your "Dropbox" folder.<br />
<br />
==Without Nautilus==<br />
<br />
If you use KDE or other non-Gnome desktop environment, you may not want to use Nautilus. Here's how to do that. Unfortunately until someone comes up with a way to bypass this, you will have to use Nautilus for the set-up. Once Dropbox is installed, you can safely remove Nautilus.<br />
<br />
#Install Dropbox using Nautilus with the instructions above. If you start Nautilus with the "--no-desktop" option it won't take over your environment.<br />
#Stop Nautilus by doing "killall nautilus".<br />
#There will be three directories in your home directory called: ".dropbox-dist", ".dropbox", and "Dropbox".<br />
#You will see a daemon running called "dropboxd" running out of the ".dropbox-dist" directory. Use this to start and stop Dropbox. You can put "~/.dropbox-dist/dropboxd" in your startup scripts if you wish.<br />
#Move files into "Dropbox" to sync them.<br />
#".dropbox" holds configuration databases and caches for Dropbox. Don't touch this.<br />
<br />
Enjoy!</div>Nedluddhttps://wiki.archlinux.org/index.php?title=SSH_keys&diff=48332SSH keys2008-08-28T20:56:33Z<p>Nedludd: /* Using ssh-agent and x11-ssh-askpass */</p>
<hr />
<div>[[Category:Networking (English)]]<br />
[[Category:Security (English)]]<br />
[[Category:HOWTOs (English)]]<br />
<br />
{{i18n_links_start}}<br />
{{i18n_entry|English|Using_SSH_Keys}}<br />
{{i18n_entry|Русский|Использование_SSH_ключей}}<br />
{{i18n_links_end}}<br />
<br />
===Using SSH-keys to connect to a server===<br />
====Why use those keys?====<br />
Using ssh-keys, a public and a private key to be precise, is an easy way to connect to a server/a whole bunch of servers, using the same password ''OR'' using no password at all. You should prefer the password/ssh-agent combination!<br><br />
<br />
====Step 1: generate the keys====<br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh-keygen -b 1024 -t dsa<br />
Generating public/private dsa key pair.<br />
Enter file in which to save the key (/home/mith/.ssh/id_dsa):<br />
Enter passphrase (empty for no passphrase):<br />
Enter same passphrase again:<br />
Your identification has been saved in /home/mith/.ssh/id_dsa.<br />
Your public key has been saved in /home/mith/.ssh/id_dsa.pub.<br />
The key fingerprint is:<br />
x6:68:xx:93:98:8x:87:95:7x:2x:4x:x9:81:xx:56:94 mith@middleearth<br />
mith@middleearth||[[~]]:~ ><br />
</pre><br />
<br><br />
What did we do? We generated a 1024 bit long (<code>-b 1024</code>) public/private dsa (<code>-t dsa</code>) key pair with the <code>ssh-keygen</code> command. You can also create a rsa key (<code>-t rsa</code>). You can leave out the bit length parameter (default bit length is 1024).<br><br />
In case you don't like the standard key name you can specify a name using the <code>-f name</code> parameter.<br><br />
In the process you are asked for a place to save your keys. I kept the standard path. Then you are asked for a passphrase. <br><br />
Now there are two paths which you can follow or ''"Choose your destiny"'' (as the guy from Mortal Kombat would say):<br><br />
'''a)''' ''the short, easy but insecure way'': use no passphrase, have easy access to your remote-server, feel paranoid about someone stealing your private key<br><br />
'''b)''' ''the a bit longer, slightly less comfortable but secure way'': use a passphrase, use ssh-agent and feel safe<br />
<br />
====Step 2: copy your public key to the remote server {SAME for path A and B}====<br />
<pre><br />
mith@middleearth||[[~]]:~ > scp .ssh/id_dsa.pub mith@metawire.org:<br />
</pre><br />
<br><br />
Copy the public key (<code>id_dsa.pub</code>) to your remote server via scp (note the '''<code>:</code>''' at the end of the server address. That way the file actually ends up in our server home directory but you can specify another path if you like.<br><br />
====Step 3: login to the remote computer and put your key into the right place {SAME for path A and B}====<br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh metawire.org<br />
mith@metawire.org's password:<br />
-bash-2.05b$ mkdir .ssh/<br />
-bash-2.05b$ cat id_dsa.pub >> .ssh/authorized_keys<br />
-bash-2.05b$ rm id_dsa.pub<br />
-bash-2.05b$ chmod 700 .ssh<br />
-bash-2.05b$ chmod 600 .ssh/authorized_keys<br />
</pre><br />
<br><br />
We connect to our remote server and use cat to add the content of <code>id_dsa.pub</code> to <code>authorized_keys</code> which is in the hidden directory <code>.ssh</code>. ''NOTE:'' In case you get an error because the <code>.ssh</code> directory doesn't exist you should simply create it (<code>mkdir .ssh</code>).<br><br />
Now we remove the public key (<code>rm id_dsa.pub</code>) and set the correct permissions for <code>.ssh</code> and <code>authorized_keys</code>.<br><br />
Log out and re-login. Depending on the path you chose, you will/won't be asked for a passphrase. '''Path a ends here...'''<br />
<br><br />
<br />
====...path b continues...====<br />
Now what makes this path almost as easy as a no-passphrase key? The magic word is ssh-agent.. What it does is basically asking you once every session for the passphrase of your private key and every time you would have to type it in, <code>ssh-agent</code> does it for you. <code>ssh-agent</code> is included in the <code>openssh</code> package so no trouble there...<br><br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh-agent<br />
SSH_AUTH_SOCK=/tmp/ssh-vEGjCM2147/agent.2147; export SSH_AUTH_SOCK;<br />
SSH_AGENT_PID=2148; export SSH_AGENT_PID;<br />
echo Agent pid 2148;<br />
</pre><br />
<br><br />
When you run <code>ssh-agent</code> it will print out what environment variables it would use... Well to make <code>ssh-agent</code> use these variables run<br />
<pre><br />
mith@middleearth||[[~]]:~ > eval `ssh-agent`<br />
Agent pid 2157<br />
</pre><br />
The process id will vary for you of course. Adding <code>eval `ssh-agent`</code> to your <code>.bashrc</code> is an option so it's started every time you create a new shell.<br><br />
Now that the <code>ssh-agent</code> is running, we need to tell it that we have a private key and where that is.<br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh-add .ssh/id_dsa<br />
Enter passphrase for .ssh/id_dsa:<br />
Identity added: .ssh/id_dsa (.ssh/id_dsa)<br />
</pre><br />
<br><br />
We were asked for our passphrase, entered it, that's all. Now you can login to your remote server without having to enter your password while your private key is password-protected. Sweet isn't it? The only downside is that a new instance of <code>ssh-agent</code> needs to be created for every new console (shell) you open, that means you have to run <code>ssh-add</code> every time again on each console. There is a workaround to that with a program or rather a script called [http://www.gentoo.org/proj/en/keychain/index.xml keychain] which will be covered in the next part {...work in progress}.<br />
<br />
====Using keychain====<br />
[http://www.gentoo.org/proj/en/keychain/index.xml Keychain] manages one or more specified private keys. Once started it will ask your for the passphrase for that/each private key and stores it. That way your private key is password protected but you won't have to enter your password over and over again.<br><br />
<br><br />
Install keychain from the extra repo.<br><br />
Edit your <code>~/.bashrc</code> and add the following lines:<br />
<pre><br />
/usr/bin/keychain ~/.ssh/id_dsa<br />
[[ -f $HOME/.keychain/$HOSTNAME-sh ]] && source $HOME/.keychain/$HOSTNAME-sh<br />
</pre><br />
I am aware that not everyone is using bash. Run <code>keychain --help</code> and it will tell you how to set it up for other shells.<br />
<br><br />
Close your shell and open it again. Keychain should come up and if it's your first run it will ask your for the passphrase of the specified private key.<br />
<br />
====Using ssh-agent and x11-ssh-askpass====<br />
You need to start the ssh-agent everytime you start a new Xsession. The ssh-agent will be closed when the X session ends.<br><br />
Install x11-ssh-askpass which will ask your passphrase everytime you open a new Xsession:<br><br />
<code>sudo pacman -S x11-ssh-askpass</code><br />
<br />
Prepend this into your <code>~/.xsession</code> :<br />
<pre><br />
eval `/usr/bin/ssh-agent`<br />
SSH_ASKPASS=/usr/lib/openssh/x11-ssh-askpass ssh-add < /dev/null<br />
# then the end of the file with for example "exec dwm"<br />
</pre><br />
<br />
====SSH connection control====<br />
In ~/.ssh/config, add the following lines: <br />
host *<br />
controlmaster auto<br />
controlpath /tmp/ssh-%r@%h:%p<br />
What this does is set a "master control" socket when you make an SSH connection. The socket is named based on the <code>controlpath</code> setting (<code>%r</code> = username, <code>%h</code> = hostname, <code>%p</code> = port). <br />
<br />
This master socket is used for each successive connection after the first, as long as one connection still exists. That is, if you connect via <code>ssh myuser@myhost.com</code>, a socket named <code>/tmp/ssh-myuser@myhost.com:22</code> is created. If you then ssh again to the same host, the socket is found and the remote ssh session is told to spawn a new shell. This shell does not require a login, and spawns immediately, as you're already logged in.<br />
<br />
<br />
===PuTTY===<br />
The above procedure is a bit complicated when using PuTTY on Windows since PuTTY can't directly use keys generated by ssh-keygen. The private key needs to be converted using PuTTYgen which you can find [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html here]. The procedure is then as follows:<br />
#Generate the key pair with ssh-keygen on you Linux computer (you can log in with your usual username/password using PuTTY)<br />
#Add the public key to the ''~/.ssh/authorized_keys'' file<br />
#Move the private key to the Windows machine<br />
#Load the private key with PuTTYgen and click ''Save private key''. This will convert the key so that PuTTY can use it.<br />
#Start PuTTY, go to ''SSH''->''Auth'' and find the private key. Then simply connect to your Linux machine. You will be prompted for your username and passphrase (if you chose to enter one when you generated the keys).<br />
Note that reversing the procedure, that is, generating the key pair with PuTTYgen and converting the public key with ssh-keygen, will NOT work.<br />
<br />
<br />
===Useful links / information===<br />
* [http://www.puddingonline.com/~dave/publications/SSH-with-Keys-HOWTO/document/html-one-page/SSH-with-Keys-HOWTO.html SSH with Keys HOWTO]<br />
* [http://www.arches.uga.edu/~pkeck/ssh/ HOWTO: set up ssh keys]<br />
<!-- Not Found + [http://particle.phys.uvic.ca/doc_sshkey.html ] --><br />
* [http://www-106.ibm.com/developerworks/linux/library/l-keyc.html OpenSSH key management, Part 1]<br />
* [http://www-106.ibm.com/developerworks/linux/library/l-keyc2/ OpenSSH key management, Part 2]<br />
* [http://www-106.ibm.com/developerworks/library/l-keyc3/ OpenSSH key management, Part 3]<br />
* [http://kimmo.suominen.com/docs/ssh/ Getting started with SSH]<br />
* Manual Pages: [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-keygen&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html ssh-keygen(1)]<br />
* [http://blog.eukhost.com/2006/11/24/sharing-ssh-keys-on-2-linux-servers-to-login-without-authentication/ Sharing SSH keys on 2 linux servers]<br />
* [http://www.andremolnar.com/how_to_set_up_ssh_keys_with_putty_and_not_get_server_refused_our_key How to set up SSH keys: Frustration with "Server refused our key" [PuTTY]]<br />
* [http://blog.webhosting.uk.com/2007/04/01/securing-your-secure-shell-ssh-service/ Securing your secure shell (SSH) service]</div>Nedluddhttps://wiki.archlinux.org/index.php?title=SSH_keys&diff=48331SSH keys2008-08-28T20:56:18Z<p>Nedludd: /* Using ssh-agent and x11-ssh-askpass */</p>
<hr />
<div>[[Category:Networking (English)]]<br />
[[Category:Security (English)]]<br />
[[Category:HOWTOs (English)]]<br />
<br />
{{i18n_links_start}}<br />
{{i18n_entry|English|Using_SSH_Keys}}<br />
{{i18n_entry|Русский|Использование_SSH_ключей}}<br />
{{i18n_links_end}}<br />
<br />
===Using SSH-keys to connect to a server===<br />
====Why use those keys?====<br />
Using ssh-keys, a public and a private key to be precise, is an easy way to connect to a server/a whole bunch of servers, using the same password ''OR'' using no password at all. You should prefer the password/ssh-agent combination!<br><br />
<br />
====Step 1: generate the keys====<br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh-keygen -b 1024 -t dsa<br />
Generating public/private dsa key pair.<br />
Enter file in which to save the key (/home/mith/.ssh/id_dsa):<br />
Enter passphrase (empty for no passphrase):<br />
Enter same passphrase again:<br />
Your identification has been saved in /home/mith/.ssh/id_dsa.<br />
Your public key has been saved in /home/mith/.ssh/id_dsa.pub.<br />
The key fingerprint is:<br />
x6:68:xx:93:98:8x:87:95:7x:2x:4x:x9:81:xx:56:94 mith@middleearth<br />
mith@middleearth||[[~]]:~ ><br />
</pre><br />
<br><br />
What did we do? We generated a 1024 bit long (<code>-b 1024</code>) public/private dsa (<code>-t dsa</code>) key pair with the <code>ssh-keygen</code> command. You can also create a rsa key (<code>-t rsa</code>). You can leave out the bit length parameter (default bit length is 1024).<br><br />
In case you don't like the standard key name you can specify a name using the <code>-f name</code> parameter.<br><br />
In the process you are asked for a place to save your keys. I kept the standard path. Then you are asked for a passphrase. <br><br />
Now there are two paths which you can follow or ''"Choose your destiny"'' (as the guy from Mortal Kombat would say):<br><br />
'''a)''' ''the short, easy but insecure way'': use no passphrase, have easy access to your remote-server, feel paranoid about someone stealing your private key<br><br />
'''b)''' ''the a bit longer, slightly less comfortable but secure way'': use a passphrase, use ssh-agent and feel safe<br />
<br />
====Step 2: copy your public key to the remote server {SAME for path A and B}====<br />
<pre><br />
mith@middleearth||[[~]]:~ > scp .ssh/id_dsa.pub mith@metawire.org:<br />
</pre><br />
<br><br />
Copy the public key (<code>id_dsa.pub</code>) to your remote server via scp (note the '''<code>:</code>''' at the end of the server address. That way the file actually ends up in our server home directory but you can specify another path if you like.<br><br />
====Step 3: login to the remote computer and put your key into the right place {SAME for path A and B}====<br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh metawire.org<br />
mith@metawire.org's password:<br />
-bash-2.05b$ mkdir .ssh/<br />
-bash-2.05b$ cat id_dsa.pub >> .ssh/authorized_keys<br />
-bash-2.05b$ rm id_dsa.pub<br />
-bash-2.05b$ chmod 700 .ssh<br />
-bash-2.05b$ chmod 600 .ssh/authorized_keys<br />
</pre><br />
<br><br />
We connect to our remote server and use cat to add the content of <code>id_dsa.pub</code> to <code>authorized_keys</code> which is in the hidden directory <code>.ssh</code>. ''NOTE:'' In case you get an error because the <code>.ssh</code> directory doesn't exist you should simply create it (<code>mkdir .ssh</code>).<br><br />
Now we remove the public key (<code>rm id_dsa.pub</code>) and set the correct permissions for <code>.ssh</code> and <code>authorized_keys</code>.<br><br />
Log out and re-login. Depending on the path you chose, you will/won't be asked for a passphrase. '''Path a ends here...'''<br />
<br><br />
<br />
====...path b continues...====<br />
Now what makes this path almost as easy as a no-passphrase key? The magic word is ssh-agent.. What it does is basically asking you once every session for the passphrase of your private key and every time you would have to type it in, <code>ssh-agent</code> does it for you. <code>ssh-agent</code> is included in the <code>openssh</code> package so no trouble there...<br><br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh-agent<br />
SSH_AUTH_SOCK=/tmp/ssh-vEGjCM2147/agent.2147; export SSH_AUTH_SOCK;<br />
SSH_AGENT_PID=2148; export SSH_AGENT_PID;<br />
echo Agent pid 2148;<br />
</pre><br />
<br><br />
When you run <code>ssh-agent</code> it will print out what environment variables it would use... Well to make <code>ssh-agent</code> use these variables run<br />
<pre><br />
mith@middleearth||[[~]]:~ > eval `ssh-agent`<br />
Agent pid 2157<br />
</pre><br />
The process id will vary for you of course. Adding <code>eval `ssh-agent`</code> to your <code>.bashrc</code> is an option so it's started every time you create a new shell.<br><br />
Now that the <code>ssh-agent</code> is running, we need to tell it that we have a private key and where that is.<br />
<pre><br />
mith@middleearth||[[~]]:~ > ssh-add .ssh/id_dsa<br />
Enter passphrase for .ssh/id_dsa:<br />
Identity added: .ssh/id_dsa (.ssh/id_dsa)<br />
</pre><br />
<br><br />
We were asked for our passphrase, entered it, that's all. Now you can login to your remote server without having to enter your password while your private key is password-protected. Sweet isn't it? The only downside is that a new instance of <code>ssh-agent</code> needs to be created for every new console (shell) you open, that means you have to run <code>ssh-add</code> every time again on each console. There is a workaround to that with a program or rather a script called [http://www.gentoo.org/proj/en/keychain/index.xml keychain] which will be covered in the next part {...work in progress}.<br />
<br />
====Using keychain====<br />
[http://www.gentoo.org/proj/en/keychain/index.xml Keychain] manages one or more specified private keys. Once started it will ask your for the passphrase for that/each private key and stores it. That way your private key is password protected but you won't have to enter your password over and over again.<br><br />
<br><br />
Install keychain from the extra repo.<br><br />
Edit your <code>~/.bashrc</code> and add the following lines:<br />
<pre><br />
/usr/bin/keychain ~/.ssh/id_dsa<br />
[[ -f $HOME/.keychain/$HOSTNAME-sh ]] && source $HOME/.keychain/$HOSTNAME-sh<br />
</pre><br />
I am aware that not everyone is using bash. Run <code>keychain --help</code> and it will tell you how to set it up for other shells.<br />
<br><br />
Close your shell and open it again. Keychain should come up and if it's your first run it will ask your for the passphrase of the specified private key.<br />
<br />
====Using ssh-agent and x11-ssh-askpass====<br />
You need to start the ssh-agent everytime you start a new Xsession. The ssh-agent will be closed when the X session end.<br><br />
Install x11-ssh-askpass which will ask your passphrase everytime you open a new Xsession:<br><br />
<code>sudo pacman -S x11-ssh-askpass</code><br />
<br />
Prepend this into your <code>~/.xsession</code> :<br />
<pre><br />
eval `/usr/bin/ssh-agent`<br />
SSH_ASKPASS=/usr/lib/openssh/x11-ssh-askpass ssh-add < /dev/null<br />
# then the end of the file with for example "exec dwm"<br />
</pre><br />
<br />
====SSH connection control====<br />
In ~/.ssh/config, add the following lines: <br />
host *<br />
controlmaster auto<br />
controlpath /tmp/ssh-%r@%h:%p<br />
What this does is set a "master control" socket when you make an SSH connection. The socket is named based on the <code>controlpath</code> setting (<code>%r</code> = username, <code>%h</code> = hostname, <code>%p</code> = port). <br />
<br />
This master socket is used for each successive connection after the first, as long as one connection still exists. That is, if you connect via <code>ssh myuser@myhost.com</code>, a socket named <code>/tmp/ssh-myuser@myhost.com:22</code> is created. If you then ssh again to the same host, the socket is found and the remote ssh session is told to spawn a new shell. This shell does not require a login, and spawns immediately, as you're already logged in.<br />
<br />
<br />
===PuTTY===<br />
The above procedure is a bit complicated when using PuTTY on Windows since PuTTY can't directly use keys generated by ssh-keygen. The private key needs to be converted using PuTTYgen which you can find [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html here]. The procedure is then as follows:<br />
#Generate the key pair with ssh-keygen on you Linux computer (you can log in with your usual username/password using PuTTY)<br />
#Add the public key to the ''~/.ssh/authorized_keys'' file<br />
#Move the private key to the Windows machine<br />
#Load the private key with PuTTYgen and click ''Save private key''. This will convert the key so that PuTTY can use it.<br />
#Start PuTTY, go to ''SSH''->''Auth'' and find the private key. Then simply connect to your Linux machine. You will be prompted for your username and passphrase (if you chose to enter one when you generated the keys).<br />
Note that reversing the procedure, that is, generating the key pair with PuTTYgen and converting the public key with ssh-keygen, will NOT work.<br />
<br />
<br />
===Useful links / information===<br />
* [http://www.puddingonline.com/~dave/publications/SSH-with-Keys-HOWTO/document/html-one-page/SSH-with-Keys-HOWTO.html SSH with Keys HOWTO]<br />
* [http://www.arches.uga.edu/~pkeck/ssh/ HOWTO: set up ssh keys]<br />
<!-- Not Found + [http://particle.phys.uvic.ca/doc_sshkey.html ] --><br />
* [http://www-106.ibm.com/developerworks/linux/library/l-keyc.html OpenSSH key management, Part 1]<br />
* [http://www-106.ibm.com/developerworks/linux/library/l-keyc2/ OpenSSH key management, Part 2]<br />
* [http://www-106.ibm.com/developerworks/library/l-keyc3/ OpenSSH key management, Part 3]<br />
* [http://kimmo.suominen.com/docs/ssh/ Getting started with SSH]<br />
* Manual Pages: [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-keygen&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html ssh-keygen(1)]<br />
* [http://blog.eukhost.com/2006/11/24/sharing-ssh-keys-on-2-linux-servers-to-login-without-authentication/ Sharing SSH keys on 2 linux servers]<br />
* [http://www.andremolnar.com/how_to_set_up_ssh_keys_with_putty_and_not_get_server_refused_our_key How to set up SSH keys: Frustration with "Server refused our key" [PuTTY]]<br />
* [http://blog.webhosting.uk.com/2007/04/01/securing-your-secure-shell-ssh-service/ Securing your secure shell (SSH) service]</div>Nedludd