Go Back   The macosxhints Forums > OS X Help Requests > UNIX - General



Reply
 
Thread Tools Rating: Thread Rating: 42 votes, 5.00 average. Display Modes
Old 11-09-2002, 09:45 PM   #1
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
Switching to bash

Hello,

So I finally decided to make the switch to bash. I will hope that you can aid me a bit in this switch.

1. Do I have to change my default shell in netinfo from /bin/tcsh to /bin/bash?

2. How would I translate my aliases to bash, also my options? right now I have the following in my .cshrc:


Code:
set path=($path /Developer/Tools .)
So I get the developer tools installed as soon as I update.

Code:
set complete=enhance
bindkey "^I" complete-word-fwd
bindkey -k down history-search-forward
bindkey -k up history-search-backward
I understand bash's autocomplete is better than tcsh's, do you have to do anything or is it stock? Any good options you guys can recommend?


Code:
setenv LESS "-Mice"
setenv EDITOR pico
setenv TERM xterm-color
We all know less is better than more And the setenv for pico is because I still haven't figured out vi and emacs, they are way complicated. The last is to get color.

Code:
alias gpid 'ps wwax | grep -i "\!*" | grep -v grep | awk '\''{print $1}'\'''
alias sshnn 'ssh -l username server.org'
alias sshmt 'ssh -l username server.com'
alias buildmail 'sudo /etc/mail/build'
alias topram 'ps axmc -o pid,stat,rss,time,command | head -20'
alias block 'sudo access'
alias sql 'mysql -u root -p'
Here I have my gpid getter, basically you put in gpid name and it'll find the pid and spit it out. Then I have assorted ssh aliases for servers I visit often. Buildmail is to build the hash tables and restart sendmail when I change something, topram shows the top ram consumers on the machine, block is a command that merv helped me make to add entries to block in my access file of sendmail, and sql is so I don't have to write that long thing every time.

Code:
source /sw/bin/init.csh
fortune -a
And last I have my fink installation and fortune -a so I can get a witticism every time I open a new terminal window, it makes it a bit slower but makes me laugh sometimes.


3. Any other things I have to be careful when making the switch? anything I could've missed? Don't want to be bitten in the change.

For example I just thought of the following, I followed the tcsh readme so I can have the 'll' command, with bash would i have this command or would i have to alias it myself?

4. Is there any changes in my day to day shell commands that I should be careful with? Like to the programs perform differently or something? I'm not too keen on what exactly it means to switch shells and what differences I should be aware of.




Thanks in advance,
V
vonleigh is offline   Reply With Quote
Old 11-09-2002, 10:55 PM   #2
mervTormel
League Commissioner
 
Join Date: Jan 2002
Posts: 5,536
skip bash and go straight to zsh

whew! you really loaded this up. i suggest you keep your tcsh shell in tact as default while you get your bash legs and the bash startup ironed out in bash subshells. you'll be less crippled.

% bash

$ # now you're in a bash subshell

$ exit # return to tcsh

% bash --login # will exercise full login scriptage

there are some scripts to translate aliases and env variables; i'll try and dig them up. they almost work ;]

install a bash completion package - http://www.caliban.org/bash/index.shtml - this requires a little study

find yourself a suitable ~/.inputrc file - i just looked at mine and i can't fathom where i got it. this is where you define key bindings and readline variables that dictate some behaviors, including completion.

uh, bash aliases no habla command line args ( \!* in tcsh aliaii ), but functions do

an ll function:

ll () { ls -FlAh --color "$@" | more ; }


your day to day commands should just work.

NB: it is a considerable security risk to have the 'dot=current directory' in your path.

more, later. take it slow, and get that bash subshell working.
__________________
On a clear disk, you can seek forever.
mervTormel is offline   Reply With Quote
Old 11-10-2002, 06:10 PM   #3
mithras
Prospect
 
Join Date: Jan 2002
Posts: 17
My tips:

These are the two entries I find essential for ~/.inputrc:
Code:
set show-all-if-ambiguous on
set completion-ignore-case on
* The first tells readline to immediately show a list of matching options, rather than just hooting at you, if the first couple of letters you typed match more than one option.

* The second is more controversial - I like it, but you may not. It does what you'd expect: remove case sensitivity in autompletion.

As for .bashrc / .profile:

* First of all, note that bash distinguishes between the common startup commands, and the login-only commands, just like tcsh does with .tcshrc and .login
For example, entries in .profile will execute when you start up Terminal, but not for a subshell, such as if you do sudo -s do use a temporary root shell. For that reason I put almost all of my modifications in .bashrc

*You can drop some of your specialized aliases, like the SSH aliases, since the caliban.org completion gives you kick-ass SSH server completion.

* Prompt customization is similar, but uses the 'PS1' variable. For example, I put this in .bashrc:
Code:
if [ $UID = 0 ]; then
        export PS1="[\[\e[0;31m\]\u\[\e[0m\]@\h: \W] "
else
        export PS1="[\[\e[0;32m\]\u\[\e[0m\]@\h: \W] "
fi
which gives me
[mithras@hostname: Documents] for my prompt, or
[root@hostname: Documents] at a root shell

Have fun!
mithras is offline   Reply With Quote
Old 11-12-2002, 12:48 AM   #4
Titanium Man
Guest
 
Posts: n/a
Ditto and ditto. I also used to include

TAB: menu-complete

in my .inputrc file. If you use fink, I believe the bash completion package that merv recommended is also available there (for those of use who DO like to keep all their eggs in one basket). The bash manpage is pretty darn helpful too. Of course, (and I don't mean to be a preachy zsh user) you could give zsh a whirl (merv did mention it already). It's an sh based shell with a lot of options right out of the box. Either way, I think you'll like your new choice better than tcsh once you get to know it a bit better.
  Reply With Quote
Old 11-12-2002, 12:38 PM   #5
bluehz
MVP
 
Join Date: Jan 2002
Posts: 1,562
I have attempted to switch to bash several times - and it always seems to break too much for me to really enjoy it.

Are you jesting or should you really skip bash and go for zsh?
bluehz is offline   Reply With Quote
Old 11-12-2002, 12:50 PM   #6
mervTormel
League Commissioner
 
Join Date: Jan 2002
Posts: 5,536
zsh may have done a lot of things right. i dunno, i haven't investigated it enough for myself, but...

if:

- you're new to shells
- you feel you might be spending a good amount of time and effort in one
- you wonder what the big deal is

you might want to:

- explore what the different shell families are
- explore the caveats of the csh family
- commit to one that will minimize your pain and service you for a long time
__________________
On a clear disk, you can seek forever.
mervTormel is offline   Reply With Quote
Old 11-12-2002, 02:01 PM   #7
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
Hello,

I've gotten a few opinions telling me to actually consider zsh instead of bash. My friend even posted me his (fairly long) zshrc for info. So while I'm at it:

"- commit to one that will minimize your pain and service you for a long time"

And that would be?

Does zsh habla command line args?


V
vonleigh is offline   Reply With Quote
Old 11-12-2002, 04:21 PM   #8
bluehz
MVP
 
Join Date: Jan 2002
Posts: 1,562
So far I am not too thrilled...I entered zsh in terminal to give it a try...played a around a bit, checked out teh man pages, etc....then exited.

Now my terminal appears screwed. Whenever I open a terminal window all I get is a blank windwo, no prompt and the title bar sez "Command completed". If I close it and open it about 5 time I MIGHT get a promopt and often it sez NO MORE PROCESSES!

Don't know what thats about - but I think thats why so many of us stick to the comfort fo csh.
bluehz is offline   Reply With Quote
Old 11-12-2002, 04:32 PM   #9
mervTormel
League Commissioner
 
Join Date: Jan 2002
Posts: 5,536
Talking

shot left: shocked and amazed

What did you DO!

-- Chris Farley, Tommy Boy
mervTormel is offline   Reply With Quote
Old 11-12-2002, 04:37 PM   #10
mervTormel
League Commissioner
 
Join Date: Jan 2002
Posts: 5,536
Quote:
Originally posted by vonleigh

"- commit to one that will minimize your pain and service you for a long time"

And that would be?

Does zsh habla command line args?

do you mean

% zsh -cisx

?

yes
__________________
On a clear disk, you can seek forever.
mervTormel is offline   Reply With Quote
Old 11-12-2002, 07:20 PM   #11
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
Merv,

You lost me. If you're asking about the command line args statement, I meant as in my gpid or ll aliases (that would have to be handled by functions in bash, as you mentioned that bash no habla command line args).

If you're refering to the "and that would be" i meant, which shell, in your opinion, would be the one that would:

"minimize your pain and service you for a long time"




V


Edit: Bluehz I tried zsh and exited no problem, don't know why you're having trouble. I haven't updated to .2.2 yet though.
vonleigh is offline   Reply With Quote
Old 11-12-2002, 07:46 PM   #12
bluehz
MVP
 
Join Date: Jan 2002
Posts: 1,562
Very weird - don't know what it was - log out/in seems to have solved it.
bluehz is offline   Reply With Quote
Old 11-12-2002, 07:50 PM   #13
mervTormel
League Commissioner
 
Join Date: Jan 2002
Posts: 5,536
o i c. you made me read my own dreck. bash aliases no habla command line args.

as for zsh, i can't see that they do. an alias is just a value that gets expanded.

re: minimize pain and to serve and protect... this is something that i can't answer for anyone. one must evaluate this themselves.
__________________
On a clear disk, you can seek forever.
mervTormel is offline   Reply With Quote
Old 11-12-2002, 10:45 PM   #14
Titanium Man
Guest
 
Posts: n/a
bluezh, that sounds like something that happened to me when I first upgraded to OS 10.2, and that was resolved by moving ~/Library/Preferences/com.apple.Terminal.plist out of my Preferences folder and having it regenerate after logging out/back in. Weird. vonleigh, zsh is an sh based shell, as is bash, so aliases are set up the same way (and they're the same regarding command line args, I believe). Instead of using this (rather unsightly) alias:

alias gpid 'ps wwax | grep -i "\!*" | grep -v grep | awk '''{print $1}''''

I'd do this in bash or zsh:

gpid () {
ps ax | grep -i "$*" | grep -v grep | awk '{ print $1 }'
}

zsh allows you to have a specific directory where you store all your functions (one per file), and you don't have to enclose them in the normal brackets, so they look like a shell script. For example, the previous gpid function is in my ~/.zfuncs, and looks like this:

% which gpid
gpid () {
ps ax | grep -i "$*" | grep -v grep | awk '{ print $1 }'
}

% cat .zfuncs/gpid
ps ax | grep -i "$*" | grep -v grep | awk '{ print $1 }'

bash, zsh, tcsh, whatever. In any case there is a lot to learn, so I think merv's advice about exploring various shells is good advice. If you're thinking about switching to a shell in the sh family (such as bash or zsh), the main differences you'll notice are when moving from tcsh to *sh. If you decide you don't like *sh, you can move to a different sh based shell with much fewer growing pains (the structure for setting up aliases won't change for example). Something else to consider is documentation. There are probably more bash users in the world, so it might be easier to get help with bash specific questions, but there are some knowledgeable zsh users who post here frequently (pmccann, OSXPEZ, santin, et al.) who have been helpful to me in learning about zsh. So flip a coin, pick a shell, and dive in. If you want to switch later, it won't be as big a deal as going from tcsh to *sh.
  Reply With Quote
Old 11-12-2002, 11:58 PM   #15
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
After some deliberation (and the fact that my friend that helps me out uses this shell), I've decided to give zsh a try for now.

So I got crankin' and this is what i have so far, btw, great advice TiMan, although I think i'm missing something to make it work.

I made my .zshfunc folder and put my gpid function in there as described and made it executable. Am I supposed to put that folder in my path? Maybe that's it.

I also added two more functions, the ll function and the block function:

Code:
% cat .zfuncs/ll
ll () {
ls -lag "$*" | more
}
% cat .zfuncs/block 
block () 
{
        local addr=${1} tab=" " verb="REJECT"

        grp=`grep ${addr} /etc/mail/access`

        if [ "${grp}" = "${addr}${tab}${verb}" ]; then
                echo "Duplicate entry, not added";
        else
                echo "${addr}${tab}${verb}" >> /etc/mail/access;
        fi
}
Don't know if they'll work as I haven't tried them. ll is pretty simple, block is to add an entry to my access file of sendmail. If you type in block someone@somewhere it'll add:

someone@somewhere REJECT
(with a tab between the address and REJECT)


Anyway, here's my .zshrc so far with comments:

Code:
# zsh init file

source /etc/profile
export PATH=${PATH}:/Developer/Tools
My friend told me to add the profile bit, and I added my developer tools to the path.

Code:
# PROMPT
PROMPT='%n@%m> '
RPROMPT=' %~'     # prompt for right side of screen
Next up is my prompt, so far it's only my username@host> with the path on the right, which is kinda nifty. Not very interesting to look at, but I'm hoping someone here will post some better ideas. Maybe some color to differentiate the prompt from the rest; so that for example when i tail this and then tail that and I'm scrolling up to read, I can easily identify where one tail ends and the other starts.

Code:
# ALIASES
alias ls="ls --color=auto"
# ls settings
# export 
LS_COLORS='no=00:fi=00:di=01;33:ln=01;36:pi=40;33:
so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31
;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*
.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=0
1;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;3
1:*.j
pg=01;35:*.png=01;35:*.gif=01;35:*.bmp=01;35:*.ppm
=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=0
1;35:*.png=01;35:*.mpg=01;35:*.avi=01;35:*.fli=01;
35:*.gl=01;35:*.dl=01;35:';
eval  `dircolors -b`
export ZLS_COLORS=$LS_COLORS
My friend told me to put this in for color, unfortunately I'm not getting any color anyway. Any idea how to get color?

BTW, broke it out on separate lines for readability, is only one line in the file.


Code:
# HISTORY
HISTFILE=~/.zshhistory
HISTSIZE=3000
SAVEHIST=3000
My history settings

Code:
# OPTIONS
# to show and tab through options
setopt MENU_COMPLETE
# so multiple shells share history
setopt INC_APPEND_HISTORY
# to make completion case insensitive
compctl -M '' 'm:{a-zA-Z}={A-Za-z}'
My options. Basically I"m trying to make it behave more like my tcsh shell currently does, which has some nifty options. The first one what it does is so that if i press say cd D<tab> it autocompletes to cd Directory, and if I click tab again it completes to the second option and so on. Unfortunately it shows all matches on the bottom also, which is confusing, but I can see how it could work better in the end.

The inc_append_history is so that multiple shells write to the same history as the commands are executed. The last one is the best option my friend could find so that the auto-completion is case insensitive. It seems that it's deprecated, but it's the only way we could find so that cd d<tab> completes to Directory.

Code:
source /sw/bin/init.csh
fortune -a
OK, what do you do with fink?? since this isn't a .csh shell I'm not sure what to do, this obviously gives an error.


* Things I'm still missing:

1. The ability to look back in history selectively. In other words if I type in "sudo" and click up arrow, I shouldn't be shown the history before, but the history before that starts with "sudo".

2. How to set my default editor as pico (instead of the yet unexplored emacs or vi).

3. How to get color ls and such.

4. I haven't tried moving my aliases over. Should I just include them in my .zshrc, and is the syntax any different? for example:

alias sshnn 'ssh -l username server etc'


Edit: I read up to earlier posts and loved the idea of different colored username for the prompt, but when I tried:

Code:
if [ $UID = 0 ]; then
        export PS1="[\[\e[0;31m\]\u\[\e[0m\]@\h: \W] "
else
        export PS1="[\[\e[0;32m\]\u\[\e[0m\]@\h: \W] "
fi
I got "[\[\e[0;32m\]\u\[\e[0m\]@\h: \W]" as a prompt. Any way to integrate that code with my existing RPROMPT code and make it actually display correctly?

Thanks,
V

Last edited by vonleigh; 11-13-2002 at 12:07 AM.
vonleigh is offline   Reply With Quote
Old 11-13-2002, 01:56 AM   #16
Titanium Man
Guest
 
Posts: n/a
Whew, that's quite a Christmas list you've got there, but I'll see what I can do. Check out www.dotfiles.com for some examples of a .zshrc file. Also, be sure to check out the documentation at http://zsh.sourceforge.net/. Ok about things in ~/.zfuncs, they don't have to be executable, and the don't have to have brackets:

% ls -l .zfuncs/gpid
-rw-r----- 1 timan admin 57 Nov 3 23:50 ~/.zfuncs/gpid

% cat ~/.zfuncs/gpid
ps ax | grep -i "$*" | grep -v grep | awk '{ print $1 }'

To get them to load automagically, I include

autoload -U +X ${fpath[1]}/*(:t)

in my .zshenv file. In fact, here's my .zshenv file (as it will solve your fink issue as well):

umask 027
PATH=$HOME/bin:/usr/local/bin:/usr/local/lib:/usr/bin:/bin:/usr/X11R6/lib:/usr/X11R6/include/X11:/usr/local/sbin:/usr/sbin:/sbin:/usr/lib:/X11R6/bin:/Developer/Tools
export PATH
MANPATH=/usr/share/man:/usr/bin/man:/usr/local/man:/usr/local/share/man:/usr/X11/man:/usr/man:~/man
export MANPATH
if [ -f /sw/bin/init.sh ]; then . /sw/bin/init.sh ; fi

MAIL=/var/mail/$USER

cdpath=(~)
zdotdir=$HOME
fpath=($zdotdir/.zfuncs $fpath)
autoload -U +X ${fpath[1]}/*(:t)

Here's a bit from my .zshrc that will answer your ls and editor questions:

LS_COLORS='di=36:fi=32:ln=35:pi=5:so=5:bd=5:cd=5:or=31:mi=0:ex=31:*.rpm=90'
export LS_COLORS

myeditor () {
if [ -e /sw/bin/nano ]; then
export EDITOR='nano -cw'
else
export EDITOR='pico -w'
fi
}
myeditor

I've had to do 'export LS_COLORS' to get the colors to appear. The myeditor function is in case I don't have nano installed using fink, it'll default to pico. Regarding 'fortune -a', you'll want to put that in .zprofile, since that's for shells with output to a terminal, ie, interactive shells. Regarding your aliases, yes, many people do put them in their .zshrc file, but I got the idea from merv to put them in their own file (in my case it's called ~/.aliases), and I include the line

if [ -f ~/.aliases ]; then . ~/.aliases ; fi

in my .zshrc file. Hmm, what else? Oh, the prompt. The syntax is different in zsh and in bash. Here's mine:

myprompt () {
local WHITE=$'%{\e[0;37m%}'
local GREEN=$'%{\e[0;32m%}'
local NOCLR=$'%{\e[0;0m%}'
local RED=$'%{\e[0;31m%}'
local BLUE=$'%{\e[0;34m%}'
local CYAN=$'%{\e[0;36m%}'
local VIOLET=$'%{\e[0;35m%}'
local NEWLINE=$'\n'
if [ $UID = 0 ]; then #I am root
PS1="${CYAN}{${RED}%(00t:DING!:%D{%I:%M %p}) %~${CYAN}}$BLUE%(2L:(%L):)$CYAN%# $
{NOCLR}"
else #I'm not root
PS1="${CYAN}{${WHITE}%(00t:DING!:%D{%I:%M %p}) %~${CYAN}}$BLUE%(2L:(%L):)$CYAN%# ${NOCLR}"
fi
}
myprompt

Unwieldy as hell? Yep. Do a search on this forum (and others) on compinstall, or just type the command in and go with the flow (backup your .zshrc first). It takes 20 minutes or so to get set up (mainly because there're so many options), but you'll be able start taking advantage of zsh if you do. Oh, and one last tidbit before I sleep. Regarding ssh completetion, look here:

http://forums.macosxhints.com/showth...&highlight=zsh

By the way: I have no idea what I'm doing in zsh, so disregard everything you've just read :-) If I have a complaint about zsh, it's that there are maybe TOO MANY options. Anyway, search this forum for posts on zsh, check the manpages (man zshall), check out www.dotfiles.com and zsh.sourceforge.net, and post if you get stuck. I know that you'll be able to find help with zsh here if you need it, just as I have many times. Sorry for the hugemongous post, everyone.
  Reply With Quote
Old 11-13-2002, 02:47 AM   #17
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
Hello,

Thanks for writing timan, unfortunately I'm still having some troubles:

1. I get the following error when I add:

autoload -U +X ${fpath[1]}/*(:t)

to my .zshenv file:

/Users/vonleigh/.zshenv:3: no matches found: /usr/share/zsh/site-functions/*(:t)

And my functions still don't work, the one I was trying was ll:

% cat .zfuncs/ll
ls -lag "$*" | more


2. I like your prompt, very interesting and amusingly it shows up in color, but here's what shows up:

{11:42 PM
~}(2)% exit
Is there supposed to be a 2 in there like that? what does yours look like?

Last, my fink commands aren't being recognized, maybe I need to add the path somewhere; as in, if i type "fortune" i get command not found.



Thanks,
V
vonleigh is offline   Reply With Quote
Old 11-13-2002, 02:57 AM   #18
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
Oh, in that thread you referenced timan, I found how to do history search with up/down arrow (as in if you type something before doing up/down arrow you get search and not just the last entry)


bindkey "^[[A" up-line-or-search ## up arrow for back-history-search
bindkey "^[[B" down-line-or-search ## down arrow for fwd-history-search


Also in that thread, got fink to work by using:

[ -f /sw/bin/init.sh ] && source /sw/bin/init.sh

I guess all I need now is to get a nicer prompt, resolve the

.zshenv:3: no matches found: /usr/share/zsh/site-functions/*(:t)

error and I'll be set. Thanks all for your help so far.

V

Last edited by vonleigh; 11-13-2002 at 03:03 AM.
vonleigh is offline   Reply With Quote
Old 11-13-2002, 03:39 AM   #19
vonleigh
All Star
 
Join Date: Jan 2002
Posts: 579
Found another problem:

Even though I have:

PATH=$HOME/bin:/usr/local/bin:/usr/local/lib:/usr/bin:/bin:/usr/X11R6/lib:/usr/X11R6/include/X11:/usr/local/sbin:/usr/sbin:/sbin:/usr/lib:/X11R6/bin:/Developer/Tools
export PATH
MANPATH=/usr/share/man:/usr/bin/man:/usr/local/man:/usr/local/share/man:/usr/X11/man:/usr/man:~/man
export MANPATH

In my .zshenv file, It can't find the mysql command. In tcsh:

% which mysql
/usr/local/bin/mysql

But in zsh:

% which mysql
mysql not found

Something tells me it ain't loading from the .zshenv file, because:

% echo $PATH /sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/Developer/Tools:/usr/X11R6/bin




V
vonleigh is offline   Reply With Quote
Old 11-13-2002, 10:59 AM   #20
Titanium Man
Guest
 
Posts: n/a
vonleigh, it sounds like you're executing zsh by typing 'zsh', which will execute a subshell--that's why you get the (2) in the prompt if you're using my prompt. After making changes to .zshrc or .zshenv, open a new term window, and try typing 'exec zsh'. This will launch zsh, but it won't be a sub-shell of tcsh. To get back to tcsh, simply type 'exec tcsh'. I'm not sure what's going on with your $PATH yet. Regarding the functions error, did you include the two lines above

autoload -U +X ${fpath[1]}/*(:t)

from my .zshenv? In other words, try this:

zdotdir=$HOME
fpath=($zdotdir/.zfuncs $fpath)
autoload -U +X ${fpath[1]}/*(:t)

Really, the default location of zdotdir will be $HOME, but it never hurts to put that in anyway just to be safe.
  Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT -5. The time now is 05:35 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.