Apple UNIX

From HaFrWiki
Jump to: navigation, search

The underwater operating system of Apple SnowLeopard is based on Unix. So use the power of Unix in Apple Mac.

Useful Unix Utilities

Program Description Usage Example
bc Basic Calculator, type 2+2 and press return.  
kill Max OS X offers no shortage of ways to cut the cord on programs that seems to be locked up or running amok. Use the Activity Monitor or use kill.
First get the ID number running top.
 
open Launch programs  
ps Process Status (ps) is another way to get a quick look at all running programs. For the best results use the -e and the -f flags. ps -ef
shutdown Shutdown with the -h flags has its advantages, because it gives the user more control. shutdown -h
tar, gzip, zip Compressed Archive files  
top Running top (table of processes) lists every program currently running. top -u
xattr Manage the extended attributes of Mac files, invisible metadata describing all kind of characteristics of every file.  
alias Shortcuts for commands alias la='ls -Al'
nano, emacs, vim editors  
grep Grep is a filter and is used in combination with other programs.  
find Terrible powerful program with a lot of features. find . -name "fn" -type f -print 2>/dev/null
mdfind MedaData find mdfind 'kMDItenFlashOnOff == "1"'
launchd Launching System Programs  
ftp File Transfer Program  

Example Process Finding

If you are running a terminal program, you may wanna find if it is still running using one of the above tools.
Assume you are running the following program which runs in an infinite loop (forever) in a Terminal window.

$ php FormulaExec.php

To see the program PID you can use:

$ ps -e 
  PID TTY           TIME CMD
    1 ??         2:44.97 /sbin/launchd
   46 ??         0:48.23 /usr/sbin/syslogd
  ...
  528 ttys000    0:01.81 login -pfl HaFrMpro /bin/bash -c exec -la bash /bin/bash
  542 ttys000    0:00.08 -bash
 3002 ttys000    0:00.01 tail -f -n 64 /Applications/MAMP/logs/php_error.log
  536 ttys001    0:01.76 login -pfl HaFrMpro /bin/bash -c exec -la bash /bin/bash
  644 ttys001    0:00.18 -bash
10842 ttys001    0:00.11 php FormulaExec.php
  537 ttys002    0:01.77 login -pfl HaFrMpro /bin/bash -c exec -la bash /bin/bash
  668 ttys002    0:00.76 -bash
10969 ttys002    0:00.00 ps -e
   ...
$

If you use:

$ ps -e | grep -i 'formulaexec'
10842 ttys001    0:00.12 php FormulaExec.php
11001 ttys002    0:00.01 grep -i formulaexec
$ 

Alternative you can use the top command which opens a monitor on top of the screen (ends by Ctrl-C):

$ top
top - 15:43:44 up 41 days, 20:28,  0 users,  load average: 4.22, 4.07, 3.55
Tasks:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  6.8 sy, 37.5 ni, 54.8 id,  0.1 wa,  0.0 hi,  0.4 si,  0.0 st
KiB Mem:  32142684 total, 30160744 used,  1981940 free,     1712 buffers
KiB Swap:        0 total,        0 used,        0 free, 24802844 cached

   PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                           
     1 harmfrie  20   0 17956 3220 2664 S   0.0  0.0   0:00.19 bash                                                              
     7 harmfrie  20   0 21684 2328 1900 R   0.0  0.0   0:00.02 top                                                               

Prevent hangup

Closing the terminal kills the process.
Can I run a command in such a way that I can close the terminal without killing the process? The answer is the programs nohup and disown.

$ nohup redshift &

or

$ redshift &
$ disown

or

$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
$ bg
$ disown
$ exit

All of the above may not work properly, try instead:

# Suppose for some reason Ctrl+Z is also not working, go to another terminal, find the process id (using ps) and run:
# The command kill -20 (SIGTSTP) will suspend the process 
$ kill -20 PID 
# The command kill -18 (SIGCONT) will resume the process, in background.
$ kill -18 PID
# So now, closing both your terminals won't stop your process.
# Just remember to do the disown %1 in the first terminal before closing it. 


See

Server Broken Pipes

For keeping the connection alive, you can check in /etc/ssh_config the line where it says ServerAliveInterval, that tells you how often (in seconds) your computer is gonna send a null packet to keep the connection alive.
If you have a 0 in there that indicates that your computer is not trying to keep the connection alive (it is disabled), otherwise it tells you how often (in seconds) it is sending the aforementioned packet.
Try putting 120 or 240, if it is still killing your connection, you can go lower, maybe to 5, if with that number it doesn't happen, maybe it is your router who is dumping the connection to free memory.

Example

ServerAliveInterval 10

See

Screen

Screen is a full-screen software program that can be used to multiplexes a physical console between several processes (typically interactive shells). It offers a user to open several separate terminal instances inside a one single terminal window manager.

Entering Screen

# Enter screen
$ screen

# Do something such as installing something
$ git clone xxxx

# Detach your screen using Ctrl-A-d
[detached]
$ 

# Re-Attach Screen using
$ screen -r



The screen application is very useful, if you are dealing with multiple programs from a command line interface and for separating programs from the terminal shell. It also allows you to share your sessions with others users and detach/attach terminal sessions.

Leaving Screen

There are 2 (two) ways to leaving the screen.

  • Ctrl-A and D to detach the screen.
  • Ctrl-A and K to kill the screen.

That’s some of screen usage on daily basis. There are still a lot of features inside the screen command. You may see screen man page for more detail.


  • TecMint Screen. Command examples to manage Linux terminals TecMint Screen.

cron replacement

Cronjobs and other deamons are not allowed on most Hosting Service Providers. An alternative maybe EasyCron and setcronjob

  • easycron, has a free plan for simple cronjobs.
  • setcronjob, not free and has the same functionality as easycron.

Apple Cron

Way back when (~2012-2014), the Mac crontab command was deprecated on MacOS, and the Apple documentation encouraged you to use their launchd facility [1].
A blurb from Apple's crontab man page:

“Darwin note: Although cron and crontab are officially supported under Darwin, their functionality has been absorbed into launchd, which provides a more flexible way of automatically executing commands.
See launchctl for more information.”

Launchd and Launchctl Example job description in a plist-file

Locations of the files

# Location of the LaunchAgents which run under the user own name (and is logged in).
$ cd $HOME/Library/LaunchAgents

# Location for the Deamons for running jobs without logged in user.
$ cd /Library/LaunchDeamons

# Location for the LaunchAgents which run as root when the user is logged in.
$ cd /Library/LaunchAgents

Launch list under MacOS

$ lanchctl load com.alvin.crontabtest.plist

Unlaunch

# To see all launched 
$ sudo launchctl list

# To unlaunch a deamon
$ sudo launchctl remove com.alvin.crontabtest.plist

plist-file: cron.alvin.crontabtest.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.alvin.crontabtest</string>

  <key>ProgramArguments</key>
  <array>
    <string>/Users/al/bin/crontab-test.sh</string>
  </array>

  <key>Nice</key>
  <integer>1</integer>

  <key>StartInterval</key>
  <integer>60</integer>

  <key>RunAtLoad</key>
  <true/>

  <key>StandardErrorPath</key>
  <string>/tmp/AlTest1.err</string>

  <key>StandardOutPath</key>
  <string>/tmp/AlTest1.out</string>
</dict>
</plist>

Launchd Subversion and Git

com.apple.hafr.gitdaily.plist com.apple.hafr.svndaily.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
   Version history:
   1.0.1.0 - 10 Mar 2019 - First Git version based on the subversion version
-->
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.apple.hafr.gitdaily</string>

   <key>ProgramArguments</key>
   <array>
      <string>/Data/USR_iMAC/gitdaily.ksh</string>
      <string>-b</string>
   </array>

   <key>StartCalendarInterval</key>
   <array>
      <dict>
         <key>Hour</key>
         <integer>12</integer>
         <key>Minute</key>
         <integer>5</integer>
      </dict>

      <dict>
         <key>Hour</key>
         <integer>17</integer>
         <key>Minute</key>
         <integer>5</integer>
      </dict>
   </array>

   <key>StandardErrorPath</key>
   <string>/Data/USR_iMAC/daily-git.log</string>

   <key>StandardOutPath</key>
   <string>/Data/USR_iMAC/daily-git.log</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
   Version history:
   1.0.1.0 - Prod Intro
   1.0.1.1 - First version with array for schedule and adding the log to the daily.log.
-->
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.apple.hafr.svndaily</string>

   <key>ProgramArguments</key>
   <array>
      <string>/Data/USR_iMAC/svndaily.ksh</string>
      <string>-a</string>
   </array>

   <key>StartCalendarInterval</key>
   <array>
      <dict>
         <key>Hour</key>
         <integer>12</integer>
         <key>Minute</key>
         <integer>0</integer>
      </dict>

      <dict>
         <key>Hour</key>
         <integer>17</integer>
         <key>Minute</key>
         <integer>0</integer>
      </dict>
   </array>

   <key>StandardErrorPath</key>
   <string>/Data/USR_iMAC/daily.log</string>

   <key>StandardOutPath</key>
   <string>/Data/USR_iMAC/daily.log</string>
</dict>
</plist>

Examples Launchd & Launchctl

Please note that you are in the directory containing the script.

# Launches a script, 
$ launchctl load com.apple.hafr.gitdaily.plist 

# Unlaunches a script, disable an agent/job for the 'currently booted session alone'
$ launchctl unload com.apple.hafr.gitdaily.plist 

# Disables a script.
$ launchctl disable com.apple.hafr.gitdaily.plist 

# Removes the job from launchd by label. 
# This subcommand will return immediately and not block until the job has been stopped.
$ launchctl remove <name-of-the-plist-script>

# Shows a list with all system jobs!
$ sudo launchctl list
password ....

# Shows a list with all users jobs!
$ launchctl list

$ Shows the ham frielink user agents
$ launchctl list | grep -i 'hafr'
-	0	com.apple.hafr.svndaily
-	0	com.apple.hafr.gitdaily

Logrotate

Logrotate is designed to ease administration of systems that generate large numbers of log files [2].
It allows automatic rotation, compression, removal, and mailing of log files.
Each log file may be handled daily, weekly, monthly, or when it grows too large.

Install

To install use brew [3].

$ brew install logrotate

This will install logrotate in the directory /usr/local/sbin.


So to call logrotate use the full startup command:

$ /usr/local/sbin/logrotate

Configuration

Example 1

Log rotation config files are in /usr/local/etc/logrotate.d
Edit config file, i.e. I wanted to rotate some /var/log/tend_*.log files I introduced:

$ sudo nano /usr/local/etc/logrotate.d/tend.conf
Contents: 
/var/log/tend_*.log {
  daily
  copytruncate
  rotate 3
  size 10M
  compress
}

Ex2 : Gitlog files

# Create the logfile 
$ sudo nano /usr/local/etc/logrotate.d/gitlog.conf

# Enter the configuration
/Users/Shared/Data/USR_iMAC/daily-git.log {
  copytruncate
  rotate 3
  size 5M
  compress
}

Do not forget to save the file!

  • copytruncate: Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.
  • rotate count: Log files are rotated count times before being removed or mailed to the address specified in a mail directive. If count is 0, old versions are removed rather than rotated.
  • size X: Log files are rotated only if they grow bigger then size bytes. If size is followed by k, the size is assumed to be in kilobytes. If the M is used, the size is in megabytes, and if G is used, the size is in gigabytes. So size 100, size 100k, size 100M and size 100Gare all valid.
  • compress: Old versions of log files are compressed with gzip(1) by default. See also nocompress.

Test

$ sudo  /usr/local/sbin/logrotate -v -f /usr/local/etc/logrotate.d

Start service

$ sudo brew services start /usr/local/sbin/logrotate

Restart service

$ sudo brew services restart /usr/local/sbin/logrotate

Stop service

$ sudo brew services stop /usr/local/sbin/logrotate

See also

top

  • ss64.com, Launchctl man page with examples.
  • Launchd, Tutorial in Launchd and Launchctl.

References

top

  1. Alvin Alaxander, Crontab test with launchd.
  2. Linux.die.net manpage, logrotate
  3. Brew Home, please follow the instructions on this website to correctly install (home)brew.