[SOLVED] xterm & tcsh/bash: it takes up to 10 seconds for a prompt to appear (DNS issue?)
SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
xterm & tcsh/bash: it takes up to 10 seconds for a prompt to appear (DNS issue?)
Hello,
I noticed that sometimes when I open an xterm with tcsh as login shell, it takes up to 10 seconds for a prompt to appear. The fortune appears immediately.Setting "nameserver 8.8.8.8" in resolv.conf did speed things up a lot, though I'd rather not use Google's DNS servers.
(Getting a prompt also takes a long time if I just unplug my network cable.)
Why do bash and tcsh take so long for a prompt to appear? In comparison, using "mksh -l", a prompt appears almost immediately, even when there is no network access. What do bash and tcsh do that mksh doesn't?
lems
PS: For some reason, with the IP of my router as the only entry in resolv.conf, I could not connect to linuxquestions.org. I'm currently using 8.8.8.8, which works (I couldn't access this forum otherwise).
PPS: I did some more testing: using OpenDNS' servers works, too: my prompt appears immediately and I can access linuxquestions.org. I also tried using my ISP's DNS servers (as listed in my router's configuration) directly in resolv.conf: the primary DNS server seems to be problematic: with it, I can't access LQ and a prompt takes long to load. The secondary DNS server of my ISP works fine. I can access LQ and no delay regarding my prompt. Though I'd still like to know why tcsh and bash take so long when there is no network/internet connection.
Last edited by lems; 06-01-2014 at 09:55 PM.
Reason: Wording / PPS
Sorry for bumping, but I found the problem: it's because I use `hostname -s' in both of my bash and tcsh prompts. When there is no internet connection/DNS issues*, `hostname -s' takes up to ten seconds for output to appear. I now use %m in my tcsh prompt, and \h in my bash prompt. I don't know why that is (hostname needing internet connectivity), but this kind of solved it.
lems
* It seems that there were problems with my ISP's DNS server. It's working now, I can access linuxquestions.org again etc.
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
Rather than hostname -s try setting an environment variable
Code:
export HOST="`uname -n`"
I do not use BASH, but setting
Code:
PS1='${HOST}-${USER}-${PWD}:
ought to work in BASH too (I really don't know, never use it).
I have a file in /etc/profile.d named ksh.sh with which I set all custom environment variables. It is executed at log in (as are all the file in /etc/profile.d or when opening a terminal as a log in terminal (such as su -). You can simply create a little executable file in that directory to set your environment (system wide) that looks something like this:
Code:
cat ksh.sh
#!/bin/sh
#ident "$Id$"
#
# Name: $Source$
# Version: $Revision$
# Modified: $Date$
# Purpose: set local environment variables for Korn Shell
# Author: T. N. Ronayne
# Date: 1 Oct 2009
# $Log$
# Set the HOST environment variable
export HOST="`uname -n`"
# Set ksh93 visual editing mode:
if [ "$SHELL" = "/bin/ksh" ]; then
# VISUAL=emacs # ugh
# VISUAL=gmacs # double ugh
VISUAL=vi # ah, elegence
fi
# Set a default shell prompt:
#PS1='`hostname`:`pwd`# '
# Do these anyway in case sombody uses a different shell
if [ "$SHELL" = "/bin/pdksh" ]; then
PS1='! $ '
elif [ "$SHELL" = "/bin/ksh" ]; then
PS1='${HOST}-${USER}-${PWD}: '
elif [ "$SHELL" = "/bin/zsh" ]; then
PS1='%n@%m:%~%# '
elif [ "$SHELL" = "/bin/ash" ]; then
PS1='$ '
else
PS1='\u@\h:\w\$ '
fi
PS2='> '
export PS1 PS2
(all that stuff is taken from /etc/profile by the way and edited).
Routers, at least the routers I have (Linksys) lose their DNS minds periodically; i.e., the router ain't worth a damn as a DNS server.
Your ISP provides DNS service, use it. Put the flaky one second in your list in /etc/resov.conf and the more reliable one first; keep in mind that you only really need a primary and secondary DNS server.
What happens is that the first on the list will time out after some time and fall to the second, then third, then fourth and so on. It takes a long time for that to happen.
Frankly, there's nothing wrong with using Google's DNS servers (they are quick like a bunny). Of course, that's up to your personal preference.
Make your /etc/resolv.conf file look like this and you'll probably be happier:
Code:
cat /etc/resolv.conf
search com
# ISP DNS Servers
nameserver <reliable one>
nameserver <less reliable one>
# Google Free DNS Servers
nameserver 8.8.8.8
nameserver 8.8.4.4
thanks for your detailed answer, tronayne. I will try to put some of this into practice. Also thanks for the information regarding DNS servers, I must admit I've never much thought about this issue. As for the shell, I use tcsh (and, to some extent, mksh) most of the time, and I think my tcshrc is/was based on NetBSD's cshrc, which I've used a lot in the past, and there hostname -s was used, so I stuck with it.
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
Quote:
Originally Posted by volkerdi
I've heard of a similar issue with startx. Do you all think that $(uname -n) should go in there, too?
Well, I just did that from SVR4 and Solaris and carried it over to Slackware (for a lot of releases). It seems like uname -n is really quick (there's no delay, but, then, there's no discernible delay with hostname -s as far as I can see with, you know, actual DNS servers active and all). I just use the ${HOST} for terminal prompts on all my machines so I can keep track of what one I'm on at any given time and ${HOST} doesn't seem to be defined anywhere else (${HOSTNAME}, yes, ${HOST}, nope).
And I've never had a problem with startx (except for when something else wasn't cooperating). Given that I boot into run level 3 and always startx I don't know if it actually matters that it's define in /etc/profle.d/ksh.sh.
For the bash prompts, it's probably best to use the inbuilt "\h" symbol rather than calling external environment variables or commands to get it, e.g.
PS1="\h $"
Similarly for the tcsh prompt you can use %m:
set prompt = '%m > '
Neither of these rely on dns lookups.
Interestingly, the hostname command will do dns lookups despite fqdn being fully resolvable from /etc/hosts, and despite both host.conf and nsswitch.conf specifying to check local files first. BTW, I found adding domain or search entries to the resolv.conf only makes it slower as the hostname command's lookups will not only check in the root domain, but will also check the domains specified.
This perked my interest so I did a little test:
Code:
gazl@ws1:/tmp$ cat hostname.c
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
int main( int argc, char **argv)
{
char name[4096];
struct hostent *ghbn;
gethostname(name, 4096);
ghbn = gethostbyname(name);
printf("hostname is: %s\n", name);
printf("ghbn h_name: %s\n", ghbn->h_name);
return 0;
}
gazl@ws1:/tmp$ cc hostname.c && ./a.out
hostname is: ws1
ghbn h_name: ws1.nix.localdomain
The snippet above works as one would expect and will only attempt dns lookups if it can't resolve the name from /etc/hosts. Seems that for some reason the util-linux version of the 'hostname' command is attempting dns lookups when it doesn't need to. Porbably have to dig around in the source to find out what it's up to.
What's best to use in things like startx? Well, for the short hostname you could always go to the horses mouth and do a hostname="$(cat /proc/sys/kernel/hostname)", but if you need the fqdn then I'm not sure of an easy option (the domainname file is for NIS, not dns, so that's not an option). I suppose one could reference /etc/HOSTNAME, or even $HOSTNAME from the shell, but that seems a little imprecise.
Anyway, looks like avoiding using the 'hostname' command when querying from scripts might be a good idea.
The hostname command does a gethostbyname2(name,PF_INET6), in addition to the normal lookup.
Looks like the lack of ipv6 entries in /etc/hosts is what is causing an external dns lookup.
You can avoid it by, adding a ipv6 entry to your hosts file as follows:
Code:
# Interfaces on this host:
192.168.0.2 ws1.nix.localdomain ws1_eth0 ws1
::1 ws1.nix.localdomain ws1
(best to use your actual IP6 link local address if you have one, I run ip6 disabled, which is why I've used ::1 for now)
Last edited by GazL; 06-03-2014 at 11:01 AM.
Reason: typo
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
Just looking at the man page for uname (man 2 uname), it looks like uname is retrieving information from the system without reference to any outside source. Seems to me that's why I chose uname for getting the system name (without the domain) in the first place; it's been about 25 years ago (and in SVR4). Seems like it's just a handy "go read stuff from the system" utility -- until I haul out the source and look at it to see what it really does do anyway.
The hint seems to be:
Quote:
NOTES
This is a system call, and the operating system presumably knows its name, release
and version. It also knows what hardware it runs on. So, four of the fields of
the struct are meaningful. On the other hand, the field nodename is meaningless:
it gives the name of the present machine in some undefined network, but typically
machines are in more than one network and have several names. Moreover, the kernel
has no way of knowing about such things, so it has to be told what to answer here.
The same holds for the additional domainname field.
To this end Linux uses the system calls sethostname(2) and setdomainname(2). Note
that there is no standard that says that the hostname set by sethostname(2) is the
same string as the nodename field of the struct returned by uname() (indeed, some
systems allow a 256-byte hostname and an 8-byte nodename), but this is true on
Linux. The same holds for setdomainname(2) and the domainname field.
The length of the fields in the struct varies. Some operating systems or libraries
use a hardcoded 9 or 33 or 65 or 257. Other systems use SYS_NMLN or _SYS_NMLN or
UTSLEN or _UTSNAME_LENGTH. Clearly, it is a bad idea to use any of these con‐
stants; just use sizeof(...). Often 257 is chosen in order to have room for an
internet hostname.
Part of the utsname information is also accessible via /proc/sys/kernel/{ostype,
hostname, osrelease, version, domainname}.
Underlying kernel interface
Over time, increases in the size of the utsname structure have led to three succes‐
sive versions of uname(): sys_olduname() (slot __NR_oldolduname), sys_uname() (slot
__NR_olduname), and sys_newuname() (slot __NR_uname). The first one used length 9
for all fields; the second used 65; the third also uses 65 but adds the domainname
field. The glibc uname() wrapper function hides these details from applications,
invoking the most recent version of the system call provided by the kernel.
(from man 2 uname).
I suspect that I'll keep using uname for the limited purpose I have for it rather than hostname, given the above discussion; a couple of simple tests show:
Code:
time uname -n
fubar
real 0m0.00s
user 0m0.00s
sys 0m0.00s
time hostname -s
fubar
real 0m0.01s
user 0m0.01s
sys 0m0.00s
uname appears to be definitely quicker, but not that quicker: if hostname is going to the network there should be significantly more delay (I've got satellite service and it's never that quick returning from a DNS server).
I would think that, like many utilities, hostname is looking at /etc/hosts first (which is what I expect), then at the network. My hosts files all look like:
Code:
# For loopbacking.
127.0.0.1 localhost
# For public and private OpenSRF comains
127.0.1.2 public.localhost public
127.0.1.3 private.localhost private
# Local servers
192.168.1.10 fubar.lan fubar
192.168.1.15 OfficeJet
192.168.1.20 snafu.lan snafu
192.168.1.30 pita.lan pita
192.168.1.40 dofus.lan dofus
# Public servers
75.126.162.205 linuxquestions.org
74.125.224.70 maps.google.com
74.125.224.111 maps.gstatic.com
and there is no discernible delay fartin' around between machines (and little to the public servers listed -- there's no DNS look up). And, of course, I'm not using DHCP for anything, everything has a fixed IP address and unique name (some of them descriptive of actual experience).
It just seems to me like defining an environment variable (which are available to every shell program I know of without any looking anything up) is a useful way of accessing needed information; thus the way I do the system name to include it in the prompt string.
Sometimes the oldies are still better than the newbies.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.