# Best way to define common FHS environment?

**URL:** https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930
**Category:** Help
**Created:** [March 1, 2023, 9:11pm UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930 "2023-03-01T21:11:00Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![matklad](https://discourse.nixos.org/user_avatar/discourse.nixos.org/matklad/32/26467_2.png) [@matklad](https://discourse.nixos.org/u/matklad)
#### Post date: [March 1, 2023, 9:11pm UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930/1 "2023-03-01T21:11:00Z")

</div>

I have the following definition in my systemPackages, which gives me an `fhs` binary which drops me into a shell which looks like a normal Linux:

```nix
  environment.systemPackages = with pkgs; [
    (pkgs.buildFHSUserEnv {
      name = "fhs";
      targetPkgs = pkgs: with pkgs; [
        alsa-lib atk cairo cups curl dbus expat file fish fontconfig freetype
        fuse glib gtk3 libGL libnotify libxml2 libxslt netcat nspr nss openjdk8
        openssl.dev pango pkg-config strace udev vulkan-loader watch wget which
        xorg.libX11 xorg.libxcb xorg.libXcomposite xorg.libXcursor
        xorg.libXdamage xorg.libXext xorg.libXfixes xorg.libXi xorg.libXrandr
        xorg.libXrender xorg.libXScrnSaver xorg.libxshmfence xorg.libXtst
        xorg.xcbutilkeysyms zlib fontconfig.lib
      ];
      profile = ''export FHS=1'';
      runScript = "fish";
    })
    # all of my other packages
  ];

```

```plaintext
$ ls /usr/lib
"/usr/lib": No such file or directory (os error 2)

$ fhs

(fhs) $ ls /usr/lib | head -n 5
dr-xr-xr-x - nobody 1 Jan 1970 32
dr-xr-xr-x - nobody 1 Jan 1970 audit
dr-xr-xr-x - nobody 1 Jan 1970 bash
dr-xr-xr-x - nobody 1 Jan 1970 cairo
lrwxrwxrwx 69 nobody 1 Jan 1970 crt1.o -> /nix/store/aji28kaprqnrkapmfyjnnnv3ffvlaq0a-fhs-usr-target/lib/crt1.o
(fhs) $ # I can now run various unpatched vanilla binaries here

```

It works great, _except_ that there’s this frightening block of standard packages which I partially copied from somewhere, and partially append a bunch of random stuff myself.

Is there some maintained-by-someone-else package I can re-use here? I am essentially looking for `buildFHSUserEnv` specialized to a set of “standard” packages (whatever that set is at the current moment in time).

---

<div class="post-metadata">

### Author: ![figsoda](https://discourse.nixos.org/user_avatar/discourse.nixos.org/figsoda/32/7760_2.png) [@figsoda](https://discourse.nixos.org/u/figsoda)
#### Post date: [March 1, 2023, 11:02pm UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930/2 "2023-03-01T23:02:55Z")

</div>

I’m not aware of any standard set of packages, but something like this can include most of what you want

```nix
builtins.concatMap (p: p.buildInputs) config.environment.systemPackages

```

---

<div class="post-metadata">

### Author: ![cdepillabout](https://discourse.nixos.org/user_avatar/discourse.nixos.org/cdepillabout/32/410_2.png) [@cdepillabout](https://discourse.nixos.org/u/cdepillabout)
#### Post date: [March 2, 2023, 2:32am UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930/3 "2023-03-02T02:32:08Z")

</div>

I’m not super familiar with it, but I think there are various lists of packages for use with buildfhsuserenvs in nixpkgs.

For instance:

> <https://github.com/NixOS/nixpkgs/blob/3374c1ab484d602e7b0f704e276253d682b9f2d0/pkgs/build-support/appimage/default.nix#L92-L209>

Used here for example (I think):

> <https://github.com/NixOS/nixpkgs/blob/3374c1ab484d602e7b0f704e276253d682b9f2d0/pkgs/games/anki/bin.nix#L53>

---

<div class="post-metadata">

### Author: ![matklad](https://discourse.nixos.org/user_avatar/discourse.nixos.org/matklad/32/26467_2.png) [@matklad](https://discourse.nixos.org/u/matklad)
#### Post date: [March 2, 2023, 10:30am UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930/4 "2023-03-02T10:30:44Z")

</div>

Thanks, this is **exactly** what I was looking for!

---

<div class="post-metadata">

### Author: ![doronbehar](https://discourse.nixos.org/user_avatar/discourse.nixos.org/doronbehar/32/1387_2.png) [@doronbehar](https://discourse.nixos.org/u/doronbehar)
#### Post date: [April 16, 2024, 10:27am UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930/5 "2024-04-16T10:27:21Z")

</div>

I wanted to share this little script:

```sh
nix shell --impure --expr '(builtins.getFlake "nixpkgs-current").legacyPackages.${builtins.currentSystem}.buildFHSUserEnv { name = "fhs"; targetPkgs = p: with p; ['"$*"']; }' --command fhs

```

Arguments accepted are simply packages. This can also be improved to include support for additional arguments to the shell itself etc…

---

<div class="post-metadata">

### Author: ![dmarcoux](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/d/a587f6/32.png) [@dmarcoux](https://discourse.nixos.org/u/dmarcoux)
#### Post date: [July 12, 2024, 7:12am UTC](https://discourse.nixos.org/t/best-way-to-define-common-fhs-environment/25930/6 "2024-07-12T07:12:48Z")

</div>

Thank you so much for this solution, it’s been a huge help in setting up a development shell with Nix flakes.

If this can help someone else, here’s how I’ve used it in `flake.nix`:

```nix
{
  description = ".NET development environment based on the Filesystem Hierarchy Standard (FHS)";
  # https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  };

  outputs = { nixpkgs, ... } @ inputs:
  let
    system = "x86_64-linux";
    pkgs = nixpkgs.legacyPackages.${system};

    # .NET SDKs
    dotnet_sdk = (with pkgs.dotnetCorePackages; combinePackages [
      # Install all the .NET SDK versions needed here...
      # sdk_8_0
      # sdk_7_0
      sdk_6_0
    ]);
  in
  {
    # Create development shell based on the Filesystem Hierarchy Standard (FHS) with a set of
    # standard packages based on the list maintained by the appimagetools package
    #
    # buildFHSEnv -> https://nixos.org/manual/nixpkgs/stable/#sec-fhs-environments
    #
    # The packages included in appimagetools.defaultFhsEnvArgs are:
    # https://github.com/NixOS/nixpkgs/blob/fd6a510ec7e84ccd7f38c2ad9a55a18bf076f738/pkgs/build-support/appimage/default.nix#L72-L208
    devShells.${system}.default = (pkgs.buildFHSEnv (pkgs.appimageTools.defaultFhsEnvArgs // {
          name = "dotnet-development-environment";
          # Packages installed in the development shell
          targetPkgs = pkgs: with pkgs; [
            # .NET SDK
            dotnet_sdk
            # Run PowerShell scripts, which are sometimes included in NuGet packages like Playwright
            powershell
            # Timezones
            tzdata
            # Locales
            glibcLocales
          ];
          # Commands to be executed in the development shell
          profile = ''
            # Ensure that dotnet tools can find the .NET location
            export DOTNET_ROOT="${dotnet_sdk}";

            # Set LANG for locales, otherwise it is unset when running "nix-shell --pure"
            export LANG="C.UTF-8"

            # Remove duplicate commands from Bash shell command history
            export HISTCONTROL=ignoreboth:erasedups

            # Do not pollute $HOME with config files (both paths are ignored in .gitignore)
            export DOTNET_CLI_HOME="$PWD/.net_cli_home";
            export NUGET_PACKAGES="$PWD/.nuget_packages";

            # Put dotnet tools in $PATH to be able to use them
            export PATH="$DOTNET_CLI_HOME/.dotnet/tools:$PATH"
          '';
        })).env;
  };
}

```
