Meaning of First 2 Lines in Mac Terminal - macos

So I have recently begun using the terminal on my Macbook air and was wondering if anyone could provide an explanation of the first 2 lines that pop up when you open Terminal. They are as follows:
Last login: Sat Feb 20 11:53:48 on ttys000
emilys-iphone-2:~ AidanTakami$
More specifically, who is emily and why is her iPhone shown on my terminal?

You will find no other piece of software on your macbook that allows you to do more than the terminal. It may not seem like it at first, looking at that simple prompt, but the terminal literally gives you the keys-to-the-kingdom.
That said, back to your two lines. The first is a standard login response telling you when and from where your user last logged into that machine (the data is usually read from /var/log/wtmp, see man last).
The second line, your prompt, is controlled by the PS1 shell variable (see man bash (or your shell's manual)). It can be configured to your liking using the various well-documented escape codes and any constant data you include. You can temporarily change the prompt by simply typing PS1=<your wanted string>. A helpful link is Prompt magic - IBM. My favorite is PS1="\[\e[0;37m\]\D{%R}\[\e[1;34m\] \h:\w> \[\e[0m\]", which results in a prompt containing the time , hostname and path information. (in a form that can be cut-and-pasted for shell operations (e.g. cp, mv, ssh, rsync, etc...) :
14:25 alchemy:~/dev/src-c/tmp/refmt>
(note: you can adjust the colors by changing the escape codes to set the color of choice. Also above \D{%R} is the formatted time, \h is the hostname and \w is the path information. The remaining escapes set the colors and \[\e[0m\] terminates a sequence of escape codes (necessary so the proper prompt length can be computed by the shell))
There are a number of shell variables that control how the PS1 prompt behaves, such as PROMPT_DIRTRIM (which controls how many directory levels are shown in the path component if included) This information is available in your shell's manual page. You can also set separate prompts for each user. For example, for root I generally use, PS1="\[\e[1;34m\][\[\e[1;31m\]\A \[\e[1;34m\]\h\[\e[0;31m\]:\w\[\e[1;34m\]] # \[\e[0m\]" which provides immediate visual indication that I am working as root (so you can do what you need, and quickly exit to your normal user again). e.g.:
[14:27 alchemy:.../src-c/tmp/refmt] #
To make your prompt changes permanent, set the desired value in your startup file (like in your ~/.bashrc for your individual user, or in the system startup file for all users)
Hope this has helped.

Related

How to properly write an interactive shell program which can exploit bash's autocompletion mechanism

(Please, help me adjust title and tags.)
When I run connmanctl I get a different prompt,
enrico:~$ connmanctl
connmanctl>
and different commands are available, like services, technologies, connect, ...
I'd like to know how this thing works.
I know that, in general, changing the prompt can be just a matter of changing the variable PS1. However this thing alone (read "the command connmanctl changes PS1 and returns) wouldn't have any effect at all on the functionalities of the commands line (I would still be in the same bash process).
Indeed, the fact that the available commands are changed, looks to me like the proof that connmanctl is running all the time the prompt is connmanctl>, and that, upon running connmanctl, a while loop is entered with a read statement in it, followed by a bunch of commands which process the the input.
In this latter scenario that I imagine, there's not even need to change PS1, as the connmanctl> line could simply be obtained by echo -n "connmanctl> ".
The reason behind this curiosity is that I'm trying to write a wrapper to connmanctl. I've already written it, and it works as intended, except that I don't know how to properly setup the autocompletion feature, and I think that in order to do so I first need to understand what is the right way to write an interactive shell script.

Script Command -- Extra space and return added to long input

I am creating a browser-based application for interacting with my local terminal, and I'm using the script command in the terminal (actually in a Java process) to feed input and capture output to display in the browser.
I have found that the virtual terminal inside the script process has 80 columns by default, and when a line of input exceeds that number, I see unexpected behavior. When it reaches the length limit, it adds a space, then a return, then continues with the line. For example, if I input the following:
user_name ~/my/current/directory$ ls /some/really/long/path/to/some/directory/somewhere
The following is what is actually transcribed (and forwarded to my browser app):
user_name ~/my/current/directory$ ls /some/really/long/path/to/some/directory/so ^Mmewhere
Notice the so ^Mmewhere instead of somewhere.
When I hit the up arrow after that to retrieve the last input, I get something different:
user_name ~/my/current/directory$ ls /some/really/long/path/to/some/directory/som^Mmewhere
This time, instead of the extra space character, it's duplicating the m: som^Mmewhere.
What is going on here? Is it that the script command is really intended to produce text output for a human reader, and therefore favors visual formatting over executability? Is there an alternative to script that would work better for my purpose?
Edit
I should have mentioned that I'm doing this in macOS Sierra. Not sure if that makes a difference.

Bash: how to duplicate input/output from interactive scripts only in complete lines?

How can I capture the input/ output from a script in realtime (such as with tee), but line-by-line instead of character-by-character? My goal is to capture the input typed into the interactive prompts of a script only after backspaces and auto-completion have finished processing (after the RETURN key is hit).
Specifically, I am trying to create a wrapper script for ssh that creates a timestamped log of commands used on remote servers. The script, which uses tee to redirect the output for filtering, works well, but the redirected output gets jumbled with unsubmitted characters whenever I use the backspace key or the up/down keys to scroll through my remote history. For example: service test stopexitservice test stopart or cd ..logs[1Pls -al.
Perhaps there is a way to capture the terminal's scrollback and redirect that like with tee?
Update: I have found a character-based cleanup solution that does what I want most of the time. However, I am still hoping for an answer to this question (which may well be msw's answer that it is very difficult to do).
In the Unix world there are two primary modes of handling keyboard input. These are known as 'raw' in which characters are passed from the terminal to the reading program one at a time. This is the mode that editors (and such) will use because the editor needs to respond immediately when you press a key.
The other terminal discipline is called 'cooked' which is the line by line behavior that you think of as the bash line by line input where you get to backspace and the command is not executed until you press return. Ssh has to take your input in raw, character-by-character mode because it has no idea what is running on the other side. For example, if you are running an editor on the far side, it can't wait for a return before sending the key-press. So, as some have suggested, grabbing shell history on the far side is the only reasonable way to get a command-by-command record of the bash commands you typed.
I oversimplified for clarity; actually most installations of bash take input in raw mode because they allow editor like command modification. For example, Ctrl-P scrolls up the command history or Ctrl-A goes to the beginning of the line. And bash needs to be able to get those keys the moment they are typed not waiting for a return.
This is another reason that capturing on the local side is obnoxiously difficult: if you capture on the local side, the stream will be filled with Backspaces and all of bash's editing commands. To get a true transcript of what the remote shell actually executed you have to parse the character stream as if you were the remote shell. There also a problem if you run something like
vi /some_file/which_is_on_the_remote/machine
the input stream to the local ssh will be filled with movement commands snippets of text including backspaces and so on and it would be bloody difficult to figure out what is part of a bash command and what is you talking to the editor.
Few things involving computers are impossible; getting clean input from the local side of an ssh invocation is really, really hard.
I question the actual utility of recording the commands that you execute on a local or remote machine. The reason is that there is so much state which is not visible from a command log. As a simple example here's a log of two commands:
17:00$ cp important_file important_file.bak
17:15$ rm important_file
and two days later you are trying to figure out whether important_file.bak should have the contents you intended or not. Given that log you can't answer that simple question. Even if you had the sequence
16:58$ cat important_file
17:00$ cp important_file important_file.bak
17:15$ rm important_file
If you aren't capturing the output, the cat in the log will not tell you anything. Give me almost any command sequence and I can envision a scenario in which it will not give you the information you need to make sense of what was done.
For a very similar purpose I use GNU screen which offer the option to record everything you do in a shell session (INPUT/OUTPUT). The log it creates also comes with undesirable characters but I clean them with perl:
perl -ne 's/\x1b[[()=][;?0-9]*[0-9A-Za-z]?//g;s/\r//g;s/\007//g;print' < screenlog.0
I hope this helps.
Some features of screen:
http://speaking-my-language.blogspot.com/2010/09/top-5-underused-gnu-screen-features.html
Site I found the perl-oneliner:
https://superuser.com/questions/99128/removing-the-escape-characters-from-gnu-screens-screenlog-n

SSH Screen Ignoring CTRL

When I SSH into a particular server and launch screen, it ignores my CTRL+a key combo. Instead of CTRL+a c creating a new screen window, it instead acts as if I had just typed c. Other key combos fail in a similar way.
I've tried launching screen using screen -e ^jj to bind to j instead of a, but I still get the same result as above.
I tried adding a .screenrc file to my homedir that I know works on other machines, but it has no impact.
I also tried launch a zsh shell instead of bash.
Any ideas where to start to try and fix this? This basically renders screen unusable.
Thanks
screen reads commands from several configuration files during startup, as described in the FILES section of the man page or the Customizing Screen section of the User's Manual (also available, if it's installed, by typing info screen).
The files read are:
The file named by the $SYSSCREENRC environment variable (this may or may not be enabled)
/etc/screenrc
The file named by the $SCREENRC environment variable`
$HOME/.screenrc
(These interact and are searched in various ways that I don't entirely understand.)
In your particular case, based on the comments, the system on which you're running screen happens to have a /etc/screenrc file that contains an escape command that overrides the default.
A digression: in my own $HOME/.screenrc I have:
escape ^#^#
This sets the escape character to the null character, which can be entered by typing Ctrl-space. I find it easier to type, and less likely to conflict with other uses, than the default Ctrl-A. The only conflict I run into is the Emac set-mark-command function, and for that it's easy enough to type it twice.

What do I need to read to understand $PATH

I'm new to programming/development and I'm having trouble installing development tools.One of my biggest problems when installing something is understanding the shell or terminal (are they the same thing?) and how it relates to installing tools like uncrustify for example. What do I need to read to understand the shell/terminal and $PATH?
Have you tried Googling?
Environment variable
PATH (variable)
(I think you're getting good advice so far on PATH)
The most generic description of a shell is that is a program that facilitates interaction w programs. Programs facilitate 'communication' with the OS to perform work by the hardware.
There are two modes that you will normally interact with a shell.
a command-line processor, where you type in commands, letter-by-letter, word-by-word until you press the enter key. Then the shell will read what you have typed, validate that it understands the general form of what you have asked for, and then start running the 1 (or more) programs specified in what you have typed.
a batch-script processor. In this case you have assembled all of the commands you want executed into a file, and then thru 1 of several mechanisms, you arrange to have the batch-script run so it will in turn run the commands you have specified and the computer does your work for you. Have you done a Windows .Bat file? same idea, but more powerful.
So, a terminal widow is program that is responsible for a. getting input and b., printing output. When you get to the c-programming that underlies the Unix system, you are talking about a feature of the OS design which are called Standard In and Standard Out. Normal unix commands expect to read instructions from StdIn and print output to StdOut.
Of course, all good programs can get their input from files and write there output to files as well, and most programs will take over the StdIn/Out and process files instead of reading input from the keyboard and/or writing to the screen.
To return to the shell, this program that lets you type while the terminal window is open. There are numerous versions of the shell that you may run into AND have varying levels of features that support a. interactive-mode, b. batch-script mode.
To sum it up, here a diagram of what is involved (very basically) for terminal and shell
(run a) terminal-window (program)
shell-command-prompt (program) (automatically started as subprogram)
1. enter commands one at a time, with input from
a. typed at keyboard (std-in)
b. infile
and output to
a. screen (std-out)
b. outFile
program
calls OS level functions for
a. computation
b. I/O
OR 2.
(run the shell program without a terminal, usually from the cron sub-system)
shell-batch-processor
shell program reads batch-script file, 1 'statement' at a time
validate statements
run program, relying on script or cfg to provide inFile data and
indicate where to put outfile data.
I hope this helps.

Resources