From unknown Sun Jun 22 00:18:29 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#51417] [PATCH] environment: Suggest command upon 'execlp' failure. Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 26 Oct 2021 17:46:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 51417 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 51417@debbugs.gnu.org Cc: Ludovic =?UTF-8?Q?Court=C3=A8s?= X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.163527034326551 (code B ref -1); Tue, 26 Oct 2021 17:46:02 +0000 Received: (at submit) by debbugs.gnu.org; 26 Oct 2021 17:45:43 +0000 Received: from localhost ([127.0.0.1]:47487 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mfQW7-0006uA-ER for submit@debbugs.gnu.org; Tue, 26 Oct 2021 13:45:43 -0400 Received: from lists.gnu.org ([209.51.188.17]:49522) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mfQW6-0006u3-0t for submit@debbugs.gnu.org; Tue, 26 Oct 2021 13:45:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49204) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mfQW5-0007z7-Ht for guix-patches@gnu.org; Tue, 26 Oct 2021 13:45:41 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:36398) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mfQW4-0007js-EQ; Tue, 26 Oct 2021 13:45:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:Subject:To:From:in-reply-to: references; bh=aM8wzDqCcDdyxvwlmppAqf2GF2cZgYWod93QR6MS2s4=; b=V7hhEg/XoTAkHH 1Cs3bxGAuaSATQFe6+e71BxmbLqx3pWW1XNu8wXmoABBWbTh4WbPEHDbsS/EuRaYfCQXs+t13Fn2J GjvRQiUlbTeeaypbxLg7D9YM8m+CfAE/DU/pPZ6RXV4JJzPNyhZhQS/Jbato1p98kYq3nlW6PGLCM znx+UT4u/lxUjGktVNXS/Ze0c3qWKT4WKIR5soLERXCI0TaPY/txdLw/LsGCSBIe2AyULL7ajT0n9 I4uRGPTz77cgwyBoDWiEhbptWkZpqbWM3iP5EJtK78yvQXmlYJAtrdMQuWRHc/HEZz6HIAoy9rIr7 Mogrljy242+4e2Imtm1Q==; Received: from 91-160-117-201.subs.proxad.net ([91.160.117.201]:54226 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mfQW4-0007Bl-08; Tue, 26 Oct 2021 13:45:40 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Tue, 26 Oct 2021 19:45:26 +0200 Message-Id: <20211026174526.24091-1-ludo@gnu.org> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) * guix/scripts/environment.scm (launch-environment): Call 'primitive-_exit' upon 'system-error. (suggest-command-name, validate-exit-status): New procedures. (launch-environment/fork): Call 'validate-exit-status'. (launch-environment/container)[exit/status*]: New procedure. Use it instead of 'exit/status'. --- guix/scripts/environment.scm | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) Hi! Here’s the idea: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix shell coreutils -C -- name guix shell: error: name: command not found hint: Did you mean 'uname'? $ ./pre-inst-env guix shell ungoogled-chromium -- ungoogled-chromium guix shell: error: ungoogled-chromium: command not found hint: Did you mean 'chromium'? $ ./pre-inst-env guix shell supertuxkart -- supertuxcart guix shell: error: supertuxcart: command not found hint: Did you mean 'supertuxkart'? --8<---------------cut here---------------end--------------->8--- Thoughts? Ludo’. diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index 7b97a8e39a..fc55151254 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -34,6 +34,7 @@ (define-module (guix scripts environment) #:use-module (guix scripts) #:use-module (guix scripts build) #:use-module (guix transformations) + #:autoload (ice-9 ftw) (scandir) #:autoload (gnu build linux-container) (call-with-container %namespaces user-namespace-supported? unprivileged-user-namespace-supported? @@ -401,7 +402,12 @@ (define* (launch-environment command profile manifest (match command ((program . args) - (apply execlp program program args)))) + (catch 'system-error + (lambda () + (apply execlp program program args)) + (lambda _ + ;; Following established convention, exit with 127 upon ENOENT. + (primitive-_exit 127)))))) (define (child-shell-environment shell profile manifest) "Create a child process, load PROFILE and MANIFEST, and then run SHELL in @@ -552,6 +558,38 @@ (define-syntax-rule (warn exp ...) (info (G_ "All is good! The shell gets correct environment \ variables.~%"))))) +(define (suggest-command-name profile command) + "COMMAND was not found in PROFILE so display a hint suggesting the closest +command name." + (define not-dot? + (match-lambda + ((or "." "..") #f) + (_ #t))) + + (match (scandir (string-append profile "/bin") not-dot?) + (() #f) + (available + (match command + ((executable _ ...) + ;; Look for a suggestion with a high threshold: a suggestion is + ;; usually better than no suggestion. + (let ((closest (string-closest executable available + #:threshold 12))) + (unless (or (not closest) (string=? closest executable)) + (display-hint (format #f (G_ "Did you mean '~a'?~%") + closest))))))))) + +(define (validate-exit-status profile command status) + "When STATUS, an integer as returned by 'waitpid', is 127, raise a \"command +not found\" error. Otherwise return STATUS." + ;; Most likely, exit value 127 means ENOENT. + (when (eqv? (status:exit-val status) 127) + (report-error (G_ "~a: command not found~%") + (first command)) + (suggest-command-name profile command) + (exit 1)) + status) + (define* (launch-environment/fork command profile manifest #:key pure? (white-list '())) "Run COMMAND in a new process with an environment containing PROFILE, with @@ -563,7 +601,8 @@ (define* (launch-environment/fork command profile manifest #:pure? pure? #:white-list white-list)) (pid (match (waitpid pid) - ((_ . status) status))))) + ((_ . status) + (validate-exit-status profile command status)))))) (define* (launch-environment/container #:key command bash user user-mappings profile manifest link-profile? network? @@ -584,6 +623,9 @@ (define (optional-mapping->fs mapping) (and (file-exists? (file-system-mapping-source mapping)) (file-system-mapping->bind-mount mapping))) + (define (exit/status* status) + (exit/status (validate-exit-status profile command status))) + (mlet %store-monad ((reqs (inputs->requisites (list (direct-store-path bash) profile)))) (return @@ -640,7 +682,7 @@ (define (optional-mapping->fs mapping) '()) (map file-system-mapping->bind-mount mappings)))) - (exit/status + (exit/status* (call-with-container file-systems (lambda () ;; Setup global shell. base-commit: 0a42998a50e8bbe9e49142b21a570db00efe7491 -- 2.33.0 From unknown Sun Jun 22 00:18:29 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Subject: bug#51417: closed (Re: bug#51417: [PATCH] environment: Suggest command upon 'execlp' failure.) Message-ID: References: <87mtmgly8m.fsf@gnu.org> <20211026174526.24091-1-ludo@gnu.org> X-Gnu-PR-Message: they-closed 51417 X-Gnu-PR-Package: guix-patches X-Gnu-PR-Keywords: patch Reply-To: 51417@debbugs.gnu.org Date: Sat, 06 Nov 2021 22:24:02 +0000 Content-Type: multipart/mixed; boundary="----------=_1636237442-10822-1" This is a multi-part message in MIME format... ------------=_1636237442-10822-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #51417: [PATCH] environment: Suggest command upon 'execlp' failure. which was filed against the guix-patches package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 51417@debbugs.gnu.org. --=20 51417: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D51417 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1636237442-10822-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 51417-done) by debbugs.gnu.org; 6 Nov 2021 22:23:46 +0000 Received: from localhost ([127.0.0.1]:51021 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mjU6E-0002nn-KP for submit@debbugs.gnu.org; Sat, 06 Nov 2021 18:23:46 -0400 Received: from eggs.gnu.org ([209.51.188.92]:39476) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mjU6C-0002nb-Kt for 51417-done@debbugs.gnu.org; Sat, 06 Nov 2021 18:23:45 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:56170) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mjU67-0003Dc-Dy for 51417-done@debbugs.gnu.org; Sat, 06 Nov 2021 18:23:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:In-Reply-To:Date:References:Subject:To: From; bh=qLXn7XwCF2GKHCnYitnXdgihcwYAp2CVo9kzRIiosH0=; b=XVWJacyEMkN42tp0yls6 lPZiJv4x4jJGfdy8w6fBR3tmYrSvvTMXprPWSiA9Z+tHx93fKZ38Ea8lZBIrsAsQ3Rj9wqAlGnXAz I6fsSXUMY65iQ4wE0pyoFnd5BsjpA33RZJEvslSlE5nw6q3uVF/FTXOGjL+ndXcGcBs0ARHVlWbnT YrcxFFC2Y52r35okJGtYg7FNaJlZapc8s2wpFyxLznvGnEf018smFjEhViwhNPeo/TAo13nwqn0v3 MNk/LKpHD3a55YKEmCcyz576Lvq+AgiVwWN/u4zwIUYRFs59/PWJVVnYic2FJlNfD2Zv5+d7sxUiP 66jTjN9iQ+fg5Q==; Received: from 91-160-117-201.subs.proxad.net ([91.160.117.201]:55532 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mjU67-0007pU-4C for 51417-done@debbugs.gnu.org; Sat, 06 Nov 2021 18:23:39 -0400 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: 51417-done@debbugs.gnu.org Subject: Re: bug#51417: [PATCH] environment: Suggest command upon 'execlp' failure. References: <20211026174526.24091-1-ludo@gnu.org> Date: Sat, 06 Nov 2021 23:23:37 +0100 In-Reply-To: <20211026174526.24091-1-ludo@gnu.org> ("Ludovic =?utf-8?Q?Cou?= =?utf-8?Q?rt=C3=A8s=22's?= message of "Tue, 26 Oct 2021 19:45:26 +0200") Message-ID: <87mtmgly8m.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 51417-done X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Ludovic Court=C3=A8s skribis: > * guix/scripts/environment.scm (launch-environment): Call > 'primitive-_exit' upon 'system-error. > (suggest-command-name, validate-exit-status): New procedures. > (launch-environment/fork): Call 'validate-exit-status'. > (launch-environment/container)[exit/status*]: New procedure. > Use it instead of 'exit/status'. Pushed in 5d2d87fed7efcb8f0cee040125f7768bab3df3f4. Ludo=E2=80=99. ------------=_1636237442-10822-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 26 Oct 2021 17:45:43 +0000 Received: from localhost ([127.0.0.1]:47487 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mfQW7-0006uA-ER for submit@debbugs.gnu.org; Tue, 26 Oct 2021 13:45:43 -0400 Received: from lists.gnu.org ([209.51.188.17]:49522) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mfQW6-0006u3-0t for submit@debbugs.gnu.org; Tue, 26 Oct 2021 13:45:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49204) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mfQW5-0007z7-Ht for guix-patches@gnu.org; Tue, 26 Oct 2021 13:45:41 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:36398) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mfQW4-0007js-EQ; Tue, 26 Oct 2021 13:45:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:Subject:To:From:in-reply-to: references; bh=aM8wzDqCcDdyxvwlmppAqf2GF2cZgYWod93QR6MS2s4=; b=V7hhEg/XoTAkHH 1Cs3bxGAuaSATQFe6+e71BxmbLqx3pWW1XNu8wXmoABBWbTh4WbPEHDbsS/EuRaYfCQXs+t13Fn2J GjvRQiUlbTeeaypbxLg7D9YM8m+CfAE/DU/pPZ6RXV4JJzPNyhZhQS/Jbato1p98kYq3nlW6PGLCM znx+UT4u/lxUjGktVNXS/Ze0c3qWKT4WKIR5soLERXCI0TaPY/txdLw/LsGCSBIe2AyULL7ajT0n9 I4uRGPTz77cgwyBoDWiEhbptWkZpqbWM3iP5EJtK78yvQXmlYJAtrdMQuWRHc/HEZz6HIAoy9rIr7 Mogrljy242+4e2Imtm1Q==; Received: from 91-160-117-201.subs.proxad.net ([91.160.117.201]:54226 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mfQW4-0007Bl-08; Tue, 26 Oct 2021 13:45:40 -0400 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: guix-patches@gnu.org Subject: [PATCH] environment: Suggest command upon 'execlp' failure. Date: Tue, 26 Oct 2021 19:45:26 +0200 Message-Id: <20211026174526.24091-1-ludo@gnu.org> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: submit Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) * guix/scripts/environment.scm (launch-environment): Call 'primitive-_exit' upon 'system-error. (suggest-command-name, validate-exit-status): New procedures. (launch-environment/fork): Call 'validate-exit-status'. (launch-environment/container)[exit/status*]: New procedure. Use it instead of 'exit/status'. --- guix/scripts/environment.scm | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) Hi! Here’s the idea: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix shell coreutils -C -- name guix shell: error: name: command not found hint: Did you mean 'uname'? $ ./pre-inst-env guix shell ungoogled-chromium -- ungoogled-chromium guix shell: error: ungoogled-chromium: command not found hint: Did you mean 'chromium'? $ ./pre-inst-env guix shell supertuxkart -- supertuxcart guix shell: error: supertuxcart: command not found hint: Did you mean 'supertuxkart'? --8<---------------cut here---------------end--------------->8--- Thoughts? Ludo’. diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index 7b97a8e39a..fc55151254 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -34,6 +34,7 @@ (define-module (guix scripts environment) #:use-module (guix scripts) #:use-module (guix scripts build) #:use-module (guix transformations) + #:autoload (ice-9 ftw) (scandir) #:autoload (gnu build linux-container) (call-with-container %namespaces user-namespace-supported? unprivileged-user-namespace-supported? @@ -401,7 +402,12 @@ (define* (launch-environment command profile manifest (match command ((program . args) - (apply execlp program program args)))) + (catch 'system-error + (lambda () + (apply execlp program program args)) + (lambda _ + ;; Following established convention, exit with 127 upon ENOENT. + (primitive-_exit 127)))))) (define (child-shell-environment shell profile manifest) "Create a child process, load PROFILE and MANIFEST, and then run SHELL in @@ -552,6 +558,38 @@ (define-syntax-rule (warn exp ...) (info (G_ "All is good! The shell gets correct environment \ variables.~%"))))) +(define (suggest-command-name profile command) + "COMMAND was not found in PROFILE so display a hint suggesting the closest +command name." + (define not-dot? + (match-lambda + ((or "." "..") #f) + (_ #t))) + + (match (scandir (string-append profile "/bin") not-dot?) + (() #f) + (available + (match command + ((executable _ ...) + ;; Look for a suggestion with a high threshold: a suggestion is + ;; usually better than no suggestion. + (let ((closest (string-closest executable available + #:threshold 12))) + (unless (or (not closest) (string=? closest executable)) + (display-hint (format #f (G_ "Did you mean '~a'?~%") + closest))))))))) + +(define (validate-exit-status profile command status) + "When STATUS, an integer as returned by 'waitpid', is 127, raise a \"command +not found\" error. Otherwise return STATUS." + ;; Most likely, exit value 127 means ENOENT. + (when (eqv? (status:exit-val status) 127) + (report-error (G_ "~a: command not found~%") + (first command)) + (suggest-command-name profile command) + (exit 1)) + status) + (define* (launch-environment/fork command profile manifest #:key pure? (white-list '())) "Run COMMAND in a new process with an environment containing PROFILE, with @@ -563,7 +601,8 @@ (define* (launch-environment/fork command profile manifest #:pure? pure? #:white-list white-list)) (pid (match (waitpid pid) - ((_ . status) status))))) + ((_ . status) + (validate-exit-status profile command status)))))) (define* (launch-environment/container #:key command bash user user-mappings profile manifest link-profile? network? @@ -584,6 +623,9 @@ (define (optional-mapping->fs mapping) (and (file-exists? (file-system-mapping-source mapping)) (file-system-mapping->bind-mount mapping))) + (define (exit/status* status) + (exit/status (validate-exit-status profile command status))) + (mlet %store-monad ((reqs (inputs->requisites (list (direct-store-path bash) profile)))) (return @@ -640,7 +682,7 @@ (define (optional-mapping->fs mapping) '()) (map file-system-mapping->bind-mount mappings)))) - (exit/status + (exit/status* (call-with-container file-systems (lambda () ;; Setup global shell. base-commit: 0a42998a50e8bbe9e49142b21a570db00efe7491 -- 2.33.0 ------------=_1636237442-10822-1--