1

Every time I open the shell, the first line on the terminal is "bash: n: command not found". I tried to look at /etc/profile, ~/.bashrc, ~/.profile and ~/.bash_profile but I was not able to find where that "n" (I guess is a typo somewhere?) was coming from. So, then I run the command bash -x -l and the following output was generated:

++ [[ -n 5.2.26(1)-release ]]
+++ declare -p PROMPT_COMMAND
++ [[ bash: declare: PROMPT_COMMAND: not found =~ declare -a ]]
++ PROMPT_COMMAND=__vte_prompt_command
+++ printf '\033]777;preexec\033\'
++ PS0=''
++ return 0
+ for i in /etc/profile.d/*.sh /etc/profile.d/sh.local
+ '[' -r /etc/profile.d/which2.sh ']'
+ '[' mxBH '!=' himxBH ']'
+ . /etc/profile.d/which2.sh
++ case "$(basename $(readlink /proc/$$/exe))" in
++++ readlink /proc/148743/exe
+++ basename /usr/bin/bash
++ alias 'which=(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'
+ for i in /etc/profile.d/*.sh /etc/profile.d/sh.local
+ '[' -r /etc/profile.d/sh.local ']'
+ '[' mxBH '!=' himxBH ']'
+ . /etc/profile.d/sh.local
+ unset i
+ unset -f pathmunge
+ test /usr/bin/bash
+ n test -z ''
+ local runcnf=1
+ local retval=127
+ [[ himxBH == *\i* ]]
+ [[ ! -S /run/dbus/system_bus_socket ]]
+ [[ ! -x /usr/libexec/packagekitd ]]
+ [[ -n '' ]]
+ [[ ! -x /usr/libexec/pk-command-not-found ]]
+ '[' 1 -eq 1 ']'
+ /usr/libexec/pk-command-not-found n test -z ''
bash: n: command not found...
+ retval=127
+ return 127
+ PT8HOME=/opt/pt
+ export PT8HOME
+ '[' -f /home/alessandro/.bashrc ']'
+ . /home/alessandro/.bashrc
++ '[' -f /etc/bashrc ']'
++ . /etc/bashrc
+++ '[' -z '' ']'
+++ BASHRCSOURCED=Y
+++ '[' '\s-\v\$ ' ']'
+++ '[' -z __vte_prompt_command ']'
+++ shopt -s histappend
+++ shopt -s checkwinsize
+++ '[' '\s-\v\$ ' = '\s-\v\$ ' ']'
+++ PS1='[\u@\h \W]\$ '
+++ shopt -q login_shell
++ PS1='[\[\033[1;35m\]\u\[\033[0m\]@\h \W]\$ '
++ [[ /home/alessandro/.local/bin:/home/alessandro/bin:/usr/lib64/ccache:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/var/lib/snapd/snap/bin =~ /home/alessandro/\.local/bin:/home/alessandro/bin: ]]
++ '[' -d /home/alessandro/.bashrc.d ']'
++ unset rc
++ alias 'll=ls -lhtr'
++ alias 'ccomp=clang -std=c11 -Wall -Wextra'
++ alias '..=cd ..'
++ __vte_prompt_command
+++ HISTTIMEFORMAT=
+++ history 1
+++ sed 's/^ *[0-9]\+ *//'
++ local 'command=bash -x -l >> logs.txt'
++ command='bash -x -l >> logs.txt'
++ local 'pwd=~'
++ '[' /home/alessandro '!=' /home/alessandro ']'
++ pwd='~'
++ printf '\033]777;notify;Command completed;%s\033\\\033]777;precmd\033\\\033]0;%s@%s:%s\033\\' 'bash -x -l >> logs.txt' alessandro fedora '~'
++ __vte_osc7
+++ /usr/libexec/vte-urlencode-cwd
++ printf '\033]7;file://%s%s\033\' fedora /home/alessandro

This is actually just the final part of the output, but you can see how at around the middle of it there is the error "bash: n: command not found...". The problem is that I'm not able to read that output. I just know that the plus sign indicates the deepness in the script execution. So, are you able to understand where the error is coming from by reading the output?

4
  • 2
    Please post or check the content of /etc/profile.d/sh.local Commented Jul 4 at 19:02
  • 5
    the line + . /etc/profile.d/sh.local shows the shell is told to start reading commands from that file (the oddly named . command does that). However, I'm not sure it succeeds, or at least finds any commands there, since I think any commands found there should appear at a deeper nesting level (one more +, compare with which2.sh earlier there). There aren't any such commands, so the file likely doesn't exist or is empty. Anyway, the line n test -z '' seems to be what causes the error.
    – ilkkachu
    Commented Jul 4 at 20:02
  • 2
    You could try running the shell with something like PS4='+ $BASH_SOURCE: $LINENO: ' bash -x -l, it should make it print the current filename and line on each line of the execution trace.
    – ilkkachu
    Commented Jul 4 at 20:03
  • @ilkkachu you are right. The only content of /etc/profile.d/sh.local is a commented line. About PS4='+ $BASH_SOURCE: $LINENO: ' bash -x -l, this is the output: ` + /etc/profile: 71: test /usr/bin/bash + /etc/profile: 71: n test -z '' <other-stuff> + /etc/profile.d/PackageKit.sh: 30: /usr/libexec/pk-command-not-found n test -z '' bash: n: command not found... ` But content of line 71 of /etc/profile is if test "$BASH" &&\n test -z "$POSIXLY_CORRECT" &&\n test "${0#-}" != sh &&\n test -r /etc/bashrc and I do not see the problem with new line characters
    – Alessandro
    Commented Jul 5 at 18:15

2 Answers 2

1

One trick to find out which source file a given command comes from is to modify PS4 to include the source file name and line in the xtrace output. (See here and here.) E.g. run the shell with something like

PS4='+ $BASH_SOURCE: $LINENO: ' bash -x -l

In the comments, you showed that the following line, and if it's indeed in the exactly as here, with literal backslashes, it would explain the problem:

if test "$BASH" &&\n   test -z "$POSIXLY_CORRECT" &&\n   ...

In Bash, an unquoted \n is the same as just n. The backslash removes any special meaning of the following character, and gets removed itself. Not that n has a special meaning, but the backslash still gets removed. This would be different when quoted, "\n" would result in a backslash and the n.

Here, the \n in the format string "%s\n" is turned into a newline by printf, and the rest are printed as they end up after the shell's processing.

$ printf "%s\n" \n "\n" '\n'
n
\n
\n

The $'...' form of quotes is different, though, it will turn \n into a newline as part of the shell's processing, before printf sees it.

$ printf "<%s>\n" $'new\nline'
<new
line>

(printf does process backslash escapes for the format string, but not for strings printed with %s.)

So &&\n test -z ... is the same as && n test -z ..., which should explain the error.


If you want to have a && chain in a single line, you can do it without anything extra, i.e.

test "$BASH" && test -z "$POSIXLY_CORRECT" && ...

Or, if you want to split it to multiple lines, you can do that with just a newline after the && operator:

test "$BASH" &&
  test -z "$POSIXLY_CORRECT" &&
  ...

If you need to split the line anywhere else, you'll need to put a backslash at the very end of the line (with no whitespace after it), e.g.:

test "$BASH" \
  && test -z \
     "$POSIXLY_CORRECT" \
  && ...
0

In the verbose output, there is a line

n test -z ''

This is the probable reason for the error message.

You apparently searched all the standard bash startup files and found nothing. The next step would be to look if there are any files sourced in these startup files, probably

. /etc/profile.d/sh.local

which is just above the line with the erroneous n.

4
  • That xtrace output suggests that bogus n command invocation is in /etc/profile.d/sh.local. Commented Jul 5 at 10:42
  • You're right. I hadn't fully examined the output. Commented Jul 5 at 11:10
  • 1
    @StéphaneChazelas, shouldn't it show with a double + if it was in the dotted file?
    – ilkkachu
    Commented Jul 5 at 12:31
  • @ilkkachu, good point. My bad. Commented Jul 5 at 12:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .