OpenSolaris
Collectives
Discussions
Documentation
Download
Source Browser
Free CD
Log-in
|
en
Project shell
:
Shell coding style guidelines
Top Menu
Show
:
Comments
Attachments
History
Information
Print
:
Print
Print preview
Export as PDF
Export as RTF
Export as HTML
Export as XAR
Wiki code for
Shell coding style guidelines
Hide Line numbers
1: = //[DRAFT]// Bourne/Korn Shell Coding Conventions 2: 3: === // This page is currently work-in-progress until it is approved by the OS/Net community. Please send any comments to {{code}}<[[shell-discuss<EMAIL_ADDRESS>// 4: 5: === 6: 7: ---- 8: 9: **Table of Contents** 10: 11: ; [[Intro>>#intro]] 12: ; [[Rules>>#rules]] 13: : 14: ; [[General>>#general]] 15: : 16: ; [[Basic Format>>#basic_format]] 17: ; [[Commenting>>#commenting]] 18: ; [[Interpreter magic>>#interpreter_magic]] 19: ; [[Harden the script against unexpected (user) input>>#harden_your_script_against_unexpected_input]] 20: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use builtin commands if the shell provides them>>#use_builtin_commands]] 21: ; [[[[image:images/tag_perf.png||alt="[perf]"height=""]] Use blocks and not subshells if possible>>#use_blocks_not_subshells]] 22: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] use long options for "{{code}}set{{/code}}">>#use_long_options_for_set_builtin]] 23: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use {{code}}$(...){{/code}} instead of {{code}}`...`{{/code}} command substitutions>>#use_posix_command_substitutions_syntax]] 24: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] Always put the result of a {{code}}$(...){{/code}} or {{code}}$( ...;){{/code}} command substitution in quotes>>#put_command_substitution_result_in_quotes]] 25: ; [[Scripts should always set their {{code}}PATH{{/code}}>>#always_set_path]] 26: ; [[Make sure that commands from other packages/applications are really installed on the machine>>#make_sure_commands_are_available]] 27: ; [[Check how boolean values are used/implemented in your application>>#check_usage_of_boolean_variables]] 28: ; [[[[image:images/tag_i18n.png||alt="[i18n]"height=""]] The shell always operates on //characters// not bytes>>#shell_uses_characters_not_bytes]] 29: ; [[[[image:images/tag_i18n.png||alt="[i18n]"height=""]] Multibyte locales and input>>#multibyte_locale_input]] 30: ; [[[[image:images/tag_perf.png||alt="[perf]"height=""]] Only use external filters like {{code}}grep{{/code}}/{{code}}sed{{/code}}/{{code}}awk{{/code}}/etc. if you want to process lots of data with them>>#use_external_filters_only_for_large_datasets]] 31: ; [[If the first operand of a command is a variable, use {{code}}~--{{/code}}>>#use_dashdash_if_first_arg_is_variable]] 32: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use {{code}}$ export FOOBAR=val #{{/code}} instead of {{code}}$ FOOBAR=val ; export FOOBAR #{{/code}}>>#use_export]] 33: ; [[Use a subshell (e.g. {{code}}$ ( mycmd ) #{{/code}}) around places which use {{code}}set ~-- $(mycmd){{/code}} and/or {{code}}shift{{/code}}>>#use_subshell_around_set_dashdash_usage]] 34: ; [[Be careful with using TABS in script code, they are not portable between editors or platforms>>#be_careful_with_tabs_in_script_code]] 35: ; [[If you have multiple points where your application exits with an error message create a central function for this purpose>>#centralise_error_exit]] 36: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] Think about using {{code}}$ set -o nounset #{{/code}} by default>>#use_set_o_nounset]] 37: ; [[Avoid using {{code}}eval{{/code}} unless absolutely necessary>>#avoid_eval_builtin]] 38: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use the string/array concatenation operator {{code}}+={{/code}}>>#use_concatenation_operator]] 39: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}source{{/code}} instead of ’{{code}}.{{/code}} ’(dot) to include other shell script fragments>>#use_source_not_dot]] 40: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] [[image:images/tag_l10n.png||alt="[l10n]"height=""]] Use {{code}}$"..."{{/code}} instead of {{code}}gettext ... "..."{{/code}} for strings that need to be localized for different locales>>#use_builtin_localisation_support]] 41: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use {{code}}set -o noglob{{/code}} if you do not need to expand files>>#use_set_o_noglob]] 42: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}IFS={{/code}} to avoid problems with spaces in filenames>>#use_empty_ifs_to_handle_spaces]] 43: ; [[Set the message locale if you process output of tools which may be localised>>#set_locale_when_comparing_against_localised_output]] 44: ; [[Cleanup after yourself.>>#cleanup_after_yourself]] 45: ; [[Use a proper {{code}}exit{{/code}} code>>#use_proper_exit_code]] 46: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}shcomp -n scriptname.sh /dev/null{{/code}} to check for common errors>>#shell_lint]] 47: ; [[Functions>>#functions]] 48: : 49: ; [[Use functions to break up your code>>#use_functions]] 50: ; [[Do not use function names which are reserved keywords in C/C++/JAVA or the POSIX shell standard>>#do_not_reserved_keywords_for_function_names]] 51: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use ksh-style {{code}}function{{/code}}>>#use_ksh_style_function_syntax]] 52: ; [[Use a proper {{code}}return{{/code}} code>>#use_proper_return_code]] 53: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use {{code}}FPATH{{/code}} to load common functions, not {{code}}source{{/code}}>>#use_fpath_to_load_common_code]] 54: ; [[{{code}}if{{/code}}, {{code}}for{{/code}} and {{code}}while{{/code}}>>#if_for_while]] 55: : 56: ; [[Format>>#if_for_while_format]] 57: ; [[{{code}}test{{/code}} Builtin>>#test_builtin]] 58: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use "{{code}}[[ expr ]]{{/code}}" instead of "{{code}}[ expr ]{{/code}}">>#use_ksh_test_syntax]] 59: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use "{{code}}(( ... )){{/code}}" for arithmetic expressions>>#use_posix_arithmetic_expressions]] 60: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Compare exit code using arithmetic expressions expressions>>#compare_exit_code_using_math]] 61: ; [[[[image:images/tag_bourne.png||alt="[Bourne]"height=""]] Use builtin commands in conditions for {{code}}while{{/code}} endless loops>>#use_builtin_commands_in_loops]] 62: ; [[Single-line if-statements>>#single_line_if_statements]] 63: ; [[Exit Status and {{code}}if{{/code}}/{{code}}while{{/code}} statements>>#exit_status_and_if_for_while]] 64: ; [[Variable types, naming and usage>>#variables]] 65: : 66: ; [[Names of local, non-environment, non-constant variables should be lowercase>>#names_should_be_lowercase]] 67: ; [[Do not use variable names which are reserved keywords/variable names in C/C++/JAVA or the POSIX shell standard>>#do_not_reserved_keywords_for_variable_names]] 68: ; [[Always use {{code}}’{’{{/code}}+{{code}}’}’{{/code}} when using variable names longer than one character>>#use_brackets_around_long_names]] 69: ; [[//Always// put variables into quotes when handling filenames or user input>>#quote_variables_containing_filenames_or_userinput]] 70: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use typed variables if possible.>>#use_typed_variables]] 71: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Store lists in arrays or associative arrays>>#store_lists_in_arrays]] 72: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use compound variables or associative arrays to group similar variables together>>#use_compound_variables_or_lists_for_grouping]] 73: ; [[I/O>>#io]] 74: : 75: ; [[Avoid using the "{{code}}echo{{/code}}" command for output>>#avoid_echo]] 76: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}redirect{{/code}} and not {{code}}exec{{/code}} to open files>>#use_redirect_not_exec_to_open_files]] 77: ; [[[[image:images/tag_perf.png||alt="[perf]"height=""]] Avoid redirections per command when the output goes into the same file, e.g. {{code}}$ echo "foo" >xxx ; echo "bar" >>xxx ; echo "baz" >>xxx #{{/code}}>>#group_identical_redirections_together]] 78: ; [[[[image:images/tag_perf.png||alt="[perf]"height=""]] Avoid the creation of temporary files and store the values in variables instead>>#avoid_using_temporary_files]] 79: ; [[If you create more than one temporary file create an unique subdir>>#create_subdirs_for_multiple_temporary_files]] 80: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {n}<file instead of fixed file descriptor numbers>>#use_dynamic_file_descriptors]] 81: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use inline here documents instead of {{code}}echo "$x" | command{{/code}}>>#use_inline_here_documents]] 82: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use the {{code}}-r{{/code}} option of {{code}}read{{/code}} to read a line>>#use_read_r]] 83: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Print compound variables using {{code}}print -C varname{{/code}} or {{code}}print -v varname{{/code}}>>#print_compound_variables_using_print_C]] 84: ; [[Put the command name and arguments before redirections>>#command_name_before_redirections]] 85: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Enable the {{code}}gmacs{{/code}} editor mode when reading user input using the {{code}}read{{/code}} builtin>>#enable_gmacs_editor_mode_for_user_prompts]] 86: ; [[Math>>#math]] 87: : 88: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use builtin arithmetic expressions instead of external applications>>#use_builtin_arithmetic_expressions]] 89: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use floating-point arithmetic expressions if calculations may trigger a division by zero or other exceptions>>#use_floating_point_arithmetic_expressions]] 90: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}printf "%a"{{/code}} when passing floating-point values>>#use_printf_a_for_passing_float_values]] 91: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Put constant values into readonly variables>>#put_constants_into_readonly_variables]] 92: ; [[[[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Avoid string to number (and/or number to string) conversions in arithmetic expressions expressions>>#avoid_unnecessary_string_number_conversions]] 93: ; [[[[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Set {{code}}LC_NUMERIC{{/code}} when using floating-point constants>>#set_lc_numeric_when_using_floating_point]] 94: ; [[Misc>>#misc]] 95: : 96: ; [[Put {{code}}[${LINENO}]{{/code}} in your {{code}}PS4{{/code}}>>#debug_use_lineno_in_ps4]] 97: 98: == Intro 99: 100: This document describes the shell coding style used for all the SMF script changes integrated into (Open)Solaris. 101: 102: All new SMF shell code should conform to this coding standard, which is intended to match our existing C coding standard. 103: 104: When in doubt, think "what would be the C-Style equivalent ?" and "What does the POSIX (shell) standard say ?" 105: 106: == Rules 107: 108: === General 109: 110: ==== Basic Format 111: 112: Similar to {{code}}cstyle{{/code}}, the basic format is that all lines are indented by TABs or eight spaces, and continuation lines (which in the shell end with "\") are indented by an equivalent number of TABs and then an additional four spaces, e.g. 113: 114: {{{ 115: 116: cp foo bar 117: cp some_realllllllllllllllly_realllllllllllllly_long_path \ 118: to_another_really_long_path 119: 120: }}} 121: 122: The encoding used for the shell scripts is either {{code}}ASCII{{/code}} or {{code}}UTF-8{{/code}}, alternative encodings are only allowed when the application requires this. 123: 124: ==== Commenting 125: 126: Shell comments are preceded by the ’{{code}}#{{/code}}’ character. Place single-line comments in the right-hand margin. Use an extra ’{{code}}#{{/code}}’ above and below the comment in the case of multi-line comments: 127: 128: {{{ 129: 130: cp foo bar # Copy foo to bar 131: 132: # 133: # Modify the permissions on bar. We need to set them to root/sys 134: # in order to match the package prototype. 135: # 136: chown root bar 137: chgrp sys bar 138: 139: }}} 140: 141: ==== Interpreter magic 142: 143: The proper interpreter magic for your shell script should be one of these: 144: 145: {{{ 146: 147: #!/bin/sh Standard Bourne shell script 148: #!/bin/ksh -p Standard Korn shell 88 script. You should always write ksh 149: scripts with -p so that ${ENV} (if set by the user) is not 150: sourced into your script by the shell. 151: #!/bin/ksh93 Standard Korn shell 93 script (-p is not needed since ${ENV} is 152: only used for interactive shell sessions). 153: 154: }}} 155: 156: ==== Harden the script against unexpected (user) input 157: 158: Harden your script against unexpected (user) input, including command line options, filenames with blanks (or other special characters) in the name, or file input 159: 160: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use builtin commands if the shell provides them 161: 162: Use builtin commands if the shell provides them. For example ksh93s+ (ksh93, version ’s+’) delivered with Solaris (as defined by PSARC 2006/550) supports the following builtins: basename, cat, chgrp, chmod, chown, cmp, comm, cp, cut, date, dirname, expr, fds, fmt, fold, getconf, head, id, join, ln, logname, mkdir, mkfifo, mv, paste, pathchk, rev, rm, rmdir, stty, tail, tee, tty, uname, uniq, wc, sync Those builtins can be enabled via {{code}}$ builtin name_of_builtin #{{/code}} in shell scripts (note that ksh93 builtins implement exact POSIX behaviour - some commands in Solaris {{code}}/usr/bin/{{/code}} directory implement pre-POSIX behaviour. Add {{code}}/usr/xpg6/bin/:/usr/xpg4/bin{{/code}} before {{code}}/usr/bin/{{/code}} in {{code}}${PATH}{{/code}} to test whether your script works with the XPG6/POSIX versions) 163: 164: ==== [[image:images/tag_perf.png||alt="[perf]"height=""]] Use blocks and not subshells if possible 165: 166: Use blocks and not subshells if possible, e.g. use {{code}}$ { print "foo" ; print "bar" ; }{{/code}} instead of {{code}}$ (print "foo" ; print "bar") #{{/code}} - blocks are faster since they do not require to save the subshell context (ksh93) or trigger a shell child process (Bourne shell, bash, ksh88 etc.) 167: 168: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] use long options for "{{code}}set{{/code}}" 169: 170: use long options for "{{code}}set{{/code}}", for example instead of {{code}}$ set -x #{{/code}} use {{code}}$ set -o xtrace #{{/code}} to make the code more readable. 171: 172: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use {{code}}$(...){{/code}} instead of {{code}}`...`{{/code}} command substitutions 173: 174: Use {{code}}$(...){{/code}} instead of {{code}}`...`{{/code}} - {{code}}`...`{{/code}} is an obsolete construct in ksh+POSIX sh scripts and {{code}}$(...){{/code}}.is a cleaner design, requires no escaping rules, allows easy nesting etc. 175: 176: === [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] {{code}}${ ...;}{{/code}}-style command substitutions 177: 178: ksh93 has support for an alternative version of command substitutions with the syntax {{code}}${ ...;}{{/code}} which do not run in a subshell. 179: 180: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] Always put the result of a {{code}}$(...){{/code}} or {{code}}$( ...;){{/code}} command substitution in quotes 181: 182: Always put the result of {{code}}$( ... ){{/code}} or {{code}}$( ...;){{/code}} in quotes (e.g. {{code}}foo="$( ... )"{{/code}} or {{code}}foo="$( ...;)"{{/code}}) unless there is a very good reason for not doing it 183: 184: ==== Scripts should always set their {{code}}PATH{{/code}} 185: 186: Scripts should always set their {{code}}PATH{{/code}} to make sure they do not use alternative commands by accident (unless the value of {{code}}PATH{{/code}} is well-known and guaranteed to be set by the caller) 187: 188: ==== Make sure that commands from other packages/applications are really installed on the machine 189: 190: Scripts should make sure that commands in optional packages are really there, e.g. add a "precheck" block in scipts to avoid later failure when doing the main job 191: 192: ==== Check how boolean values are used/implemented in your application 193: 194: Check how boolean values are used in your application. 195: 196: For example: 197: 198: {{{ 199: 200: mybool=0 201: # do something 202: if [ $mybool -eq 1 ] ; then do_something_1 ; fi 203: 204: }}} 205: 206: could be rewritten like this: 207: 208: {{{ 209: 210: mybool=false # (valid values are "true" or "false", pointing 211: # to the builtin equivalents of /bin/true or /bin/false) 212: # do something 213: if ${mybool} ; then do_something_1 ; fi 214: 215: }}} 216: 217: or 218: 219: {{{ 220: 221: integer mybool=0 # values are 0 or 1 222: # do something 223: if (( mybool==1 )) ; then do_something_1 ; fi 224: 225: }}} 226: 227: ==== [[image:images/tag_i18n.png||alt="[i18n]"height=""]] The shell always operates on //characters// not bytes 228: 229: Shell scripts operate on characters and //not// bytes. Some locales use multiple bytes (called "multibyte locales") to represent one character 230: 231: === Note 232: 233: ksh93 has support for binary variables which explicitly operate on bytes, not characters. This is the //only// allowed exception. 234: 235: ==== [[image:images/tag_i18n.png||alt="[i18n]"height=""]] Multibyte locales and input 236: 237: Think about whether your application has to handle file names or variables in multibyte locales and make sure all commands used in your script can handle such characters (e.g. lots of commands in Solaris’s {{code}}/usr/bin/{{/code}} are //not// able to handle such values - either use ksh93 builtin constructs (which are guaranteed to be multibyte-aware) or commands from {{code}}/usr/xpg4/bin/{{/code}} and/or {{code}}/usr/xpg6/bin{{/code}}) 238: 239: ==== [[image:images/tag_perf.png||alt="[perf]"height=""]] Only use external filters like {{code}}grep{{/code}}/{{code}}sed{{/code}}/{{code}}awk{{/code}}/etc. if you want to process lots of data with them 240: 241: Only use external filters like {{code}}grep{{/code}}/{{code}}sed{{/code}}/{{code}}awk{{/code}}/etc. if a significant amount of data is processed by the filter or if benchmarking shows that the use of builtin commands is significantly slower (otherwise the time and resources needed to start the filter are far greater then the amount of data being processed, creating a performance problem). 242: 243: For example: 244: 245: {{{ 246: 247: if [ "$(echo "$x" | egrep ’.*foo.*’)" != "" ] ; then 248: do_something ; 249: done 250: 251: }}} 252: 253: can be re-written using ksh93 builtin constructs, saving several {{code}}|fork()|+|exec()|{{/code}}’s: 254: 255: {{{ 256: 257: if [[ "${x}" == ~(E).*foo.* ]] ; then 258: do_something ; 259: done 260: 261: }}} 262: 263: ==== If the first operand of a command is a variable, use {{code}}~--{{/code}} 264: 265: If the first operand of a command is a variable, use {{code}}~--{{/code}} for any command that accepts this as end of argument to avoid problems if the variable expands to a value starting with {{code}}-{{/code}}. 266: 267: === Note 268: 269: At least print, /usr/bin/fgrep, /usr/xpg4/bin/fgrep, /usr/bin/grep, /usr/xpg4/bin/grep, /usr/bin/egrep, /usr/xpg4/bin/egrep support {{code}}~--{{/code}} as "end of arguments"-terminator. 270: 271: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use {{code}}$ export FOOBAR=val #{{/code}} instead of {{code}}$ FOOBAR=val ; export FOOBAR #{{/code}} 272: 273: Use {{code}}$ export FOOBAR=val # instead of $ FOOBAR=val ; export FOOBAR #{{/code}} - this is much faster. 274: 275: ==== Use a subshell (e.g. {{code}}$ ( mycmd ) #{{/code}}) around places which use {{code}}set ~-- $(mycmd){{/code}} and/or {{code}}shift{{/code}} 276: 277: Use a subshell (e.g. {{code}}$ ( mycmd ) #{{/code}}) around places which use {{code}}set ~-- $(mycmd){{/code}} and/or {{code}}shift{{/code}} unless the variable affected is either a local one or if it’s guaranteed that this variable will no longer be used (be careful for loadable functions, e.g. ksh/ksh93’s {{code}}autoload{{/code}} !!!!) 278: 279: ==== Be careful with using TABS in script code, they are not portable between editors or platforms 280: 281: Be careful with using TABS in script code, they are not portable between editors or platforms. 282: 283: If you use ksh93 use {{code}}$’\t’{{/code}} to include TABs in sources, not the TAB character itself. 284: 285: ==== If you have multiple points where your application exits with an error message create a central function for this purpose 286: 287: If you have multiple points where your application exits with an error message create a central function for this, e.g. 288: 289: {{{ 290: 291: if [ -z "$tmpdir" ] ; then 292: print -u2 "mktemp failed to produce output; aborting." 293: exit 1 294: fi 295: if [ ! -d $tmpdir ] ; then 296: print -u2 "mktemp failed to create a directory; aborting." 297: exit 1 298: fi 299: 300: }}} 301: 302: should be replaced with 303: 304: {{{ 305: 306: function fatal_error 307: { 308: print -u2 "${progname}: $*" 309: exit 1 310: } 311: # do something (and save ARGV[0] to variable "progname") 312: if [ -z "$tmpdir" ] ; then 313: fatal_error "mktemp failed to produce output; aborting." 314: fi 315: if [ ! -d "$tmpdir" ] ; then 316: fatal_error "mktemp failed to create a directory; aborting." 317: fi 318: 319: }}} 320: 321: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] Think about using {{code}}$ set -o nounset #{{/code}} by default 322: 323: Think about using {{code}}$ set -o nounset #{{/code}} by default (or at least during the script’s development phase) to catch errors where variables are used when they are not set (yet), e.g. 324: 325: {{{ 326: 327: $ **{{code}}(set -o nounset ; print ${foonotset}){{/code}}** 328: /bin/ksh93: foonotset: parameter not set 329: 330: }}} 331: 332: ==== Avoid using {{code}}eval{{/code}} unless absolutely necessary 333: 334: Avoid using {{code}}eval{{/code}} unless absolutely necessary. Subtle things can happen when a string is passed back through the shell parser. You can use name references to avoid uses such as {{code}}eval $name="$value"{{/code}}. 335: 336: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use the string/array concatenation operator {{code}}+={{/code}} 337: 338: Use {{code}}+={{/code}} instead of manually adding strings/array elements, e.g. 339: 340: {{{ 341: 342: foo="" 343: foo="${foo}a" 344: foo="${foo}b" 345: foo="${foo}c" 346: 347: }}} 348: 349: should be replaced with 350: 351: {{{ 352: 353: foo="" 354: foo+="a" 355: foo+="b" 356: foo+="c" 357: 358: }}} 359: 360: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}source{{/code}} instead of ’{{code}}.{{/code}} ’(dot) to include other shell script fragments 361: 362: Use {{code}}source{{/code}} instead of ’{{code}}.{{/code}}’ (dot) to include other shell script fragments - the new form is much more readable than the tiny dot and a failure can be caught within the script. 363: 364: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] [[image:images/tag_l10n.png||alt="[l10n]"height=""]] Use {{code}}$"..."{{/code}} instead of {{code}}gettext ... "..."{{/code}} for strings that need to be localized for different locales 365: 366: Use $"..." instead of {{code}}gettext ... "..."{{/code}} for strings that need to be localized for different locales. {{code}}gettext{{/code}} will require a {{code}}fork()+exec(){{/code}} and reads the whole catalog each time it’s called, creating a huge overhead for localisation (and the {{code}}$"..."{{/code}} is easier to use, e.g. you only have to put a {{code}}${{/code}} in front of the catalog and the string will be localised). 367: 368: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use {{code}}set -o noglob{{/code}} if you do not need to expand files 369: 370: If you don’t expect to expand files, you can do set {{code}}-f{{/code}} ({{code}}set -o noglob{{/code}}) as well. This way the need to use {{code}}""{{/code}} is greatly reduced. 371: 372: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}IFS={{/code}} to avoid problems with spaces in filenames 373: 374: Unless you want to do word splitting, put {{code}}IFS={{/code}} at the beginning of a command. This way spaces in file names won’t be a problem. You can do {{code}}IFS=’delims’ read -r{{/code}} line to override {{code}}IFS{{/code}} just for the {{code}}read{{/code}} command. However, you can’t do this for the {{code}}set{{/code}} builtin. 375: 376: ==== Set the message locale if you process output of tools which may be localised 377: 378: Set the message locale ({{code}}LC_MESSAGES{{/code}}) if you process output of tools which may be localised 379: 380: **Example�1.�Set {{code}}LC_MESSAGES{{/code}} when testing for specific outout of the {{code}}/usr/bin/file{{/code}} utility:** 381: 382: {{{ 383: 384: # set french as default message locale 385: export LC_MESSAGES=fr_FR.UTF-8 386: 387: ... 388: 389: # test whether the file "/tmp" has the filetype "directory" or not 390: # we set LC_MESSAGES to "C" to ensure the returned message is in english 391: if [[ "$(LC_MESSAGES=C file /tmp)" = *directory ]] ; then 392: print "is a directory" 393: fi 394: 395: }}} 396: 397: === Note 398: 399: The environment variable {{code}}LC_ALL{{/code}} always overrides any other {{code}}LC_*{{/code}} environment variables (and {{code}}LANG{{/code}}, too), including {{code}}LC_MESSAGES{{/code}}. if there is the chance that {{code}}LC_ALL{{/code}} may be set replace {{code}}LC_MESSAGES{{/code}} with {{code}}LC_ALL{{/code}} in the example above. 400: 401: ==== Cleanup after yourself. 402: 403: Cleanup after yourself. For example ksh/ksh93 have an {{code}}EXIT{{/code}} trap which is very useful for this. 404: 405: === Note 406: 407: Note that the {{code}}EXIT{{/code}} trap is executed for a subshell and each subshell level can run it’s own {{code}}EXIT{{/code}} trap, for example 408: 409: {{{ 410: 411: $ **{{code}}(trap "print bam" EXIT ; (trap "print snap" EXIT ; print "foo")){{/code}}** 412: foo 413: snap 414: bam 415: 416: }}} 417: 418: ==== Use a proper {{code}}exit{{/code}} code 419: 420: Explicitly set the exit code of a script, otherwise the exit code from the last command executed will be used which may trigger problems if the value is unexpected. 421: 422: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}shcomp -n scriptname.sh /dev/null{{/code}} to check for common errors 423: 424: Use {{code}}shcomp -n scriptname.sh /dev/null{{/code}} to check for common problems (such as insecure, depreciated or ambiguous constructs) in shell scripts. 425: 426: === Functions 427: 428: ==== Use functions to break up your code 429: 430: Use functions to break up your code into smaller, logical blocks. 431: 432: ==== Do not use function names which are reserved keywords in C/C++/JAVA or the POSIX shell standard 433: 434: Do not use function names which are reserved keywords (or function names) in C/C++/JAVA or the POSIX shell standard (to avoid confusion and/or future changes/updates to the shell language). 435: 436: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use ksh-style {{code}}function{{/code}} 437: 438: It is //highly// recommended to use ksh style functions ({{code}}function foo { ... }{{/code}}) instead of Bourne-style functions ({{code}}foo() { ... }{{/code}}) if possible (and local variables instead of spamming the global namespace). 439: 440: === Warning 441: 442: The difference between old-style Bourne functions and ksh functions is one of the major differences between ksh88 and ksh93 - ksh88 allowed variables to be local for Bourne-style functions while ksh93 conforms to the POSIX standard and will use a function-local scope for variables declared in Bourne-style functions. 443: 444: Example (note that "{{code}}integer{{/code}}" is an alias for "{{code}}typeset -li{{/code}}"): 445: 446: {{{ 447: 448: # new style function with local variable 449: $ ksh93 -c ’integer x=2 ; function foo { integer x=5 ; } ; print "x=$x" 450: ; foo ; print "x=$x" ;’ 451: x=2 452: x=2 453: # old style function with an attempt to create a local variable 454: $ ksh93 -c ’integer x=2 ; foo() { integer x=5 ; } ; print "x=$x" ; foo ; 455: print "x=$x" ;’ 456: x=2 457: x=5 458: 459: }}} 460: 461: {{code}}[[usr/src/lib/libshell/common/COMPATIBILITY>>Project ksh93-integration.compatibility]]{{/code}} says about this issue: 462: 463: > Functions, defined with name() with ksh-93 are compatible with the POSIX standard, not with ksh-88. No local variables are permitted, and there is no separate scope. Functions defined with the function name syntax, maintain compatibility. This also affects function traces. 464: 465: (this issue also affects {{code}}/usr/xpg4/bin/sh{{/code}} in Solaris 10 because it is based on ksh88. This is a bug.). 466: 467: ==== Use a proper {{code}}return{{/code}} code 468: 469: Explicitly set the return code of a function - otherwise the exit code from the last command executed will be used which may trigger problems if the value is unexpected. 470: 471: The only allowed exception is if a function uses the shell’s {{code}}errexit{{/code}} mode to leave a function, subshell or the script if a command returns a non-zero exit code. 472: 473: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use {{code}}FPATH{{/code}} to load common functions, not {{code}}source{{/code}} 474: 475: Use the ksh {{code}}FPATH{{/code}} (function path) feature to load functions which are shared between scripts and not {{code}}source{{/code}} - this allows to load such a function on demand and not all at once. 476: 477: === {{code}}if{{/code}}, {{code}}for{{/code}} and {{code}}while{{/code}} 478: 479: ==== Format 480: 481: To match {{code}}cstyle{{/code}}, the shell token equivalent to the {{code}}C{{/code}} "{{code}}{{{/code}}" should appear on the same line, separated by a "{{code}};{{/code}}", as in: 482: 483: {{{ 484: 485: if [ "$x" = "hello" ] ; then 486: echo $x 487: fi 488: 489: if [[ "$x" = "hello" ]] ; then 490: print $x 491: fi 492: 493: for i in 1 2 3; do 494: echo $i 495: done 496: 497: for ((i=0 ; i < 3 ; i++)); do 498: print $i 499: done 500: 501: while [ $# -gt 0 ]; do 502: echo $1 503: shift 504: done 505: 506: while (( $# > 0 )); do 507: print $1 508: shift 509: done 510: 511: }}} 512: 513: ==== {{code}}test{{/code}} Builtin 514: 515: DO NOT use the test builtin. Sorry, executive decision. 516: 517: In our Bourne shell, the {{code}}test{{/code}} built-in is the same as the "[" builtin (if you don’t believe me, try "type test" or refer to {{code}}usr/src/cmd/sh/msg.c{{/code}}). 518: 519: So please do not write: 520: 521: {{{ 522: 523: if test $# -gt 0 ; then 524: 525: }}} 526: 527: instead use: 528: 529: {{{ 530: 531: if [ $# -gt 0 ] ; then 532: 533: }}} 534: 535: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use "{{code}}[[ expr ]]{{/code}}" instead of "{{code}}[ expr ]{{/code}}" 536: 537: Use "{{code}}[[ expr ]]{{/code}}" instead of "{{code}}[ expr ]{{/code}}" if possible since it avoids going through the whole pattern expansion/etc. machinery and adds additional operators not available in the Bourne shell, such as short-circuit {{code}}&&{{/code}} and {{code}}||{{/code}}. 538: 539: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use "{{code}}(( ... )){{/code}}" for arithmetic expressions 540: 541: Use "{{code}}(( ... )){{/code}}" instead of "{{code}}[ expr ]{{/code}}" or "{{code}}[[ expr ]]{{/code}}" expressions. 542: 543: Example: Replace 544: 545: {{{ 546: 547: i=5 548: # do something 549: if [ $i -gt 5 ] ; then 550: 551: }}} 552: 553: with 554: 555: {{{ 556: 557: i=5 558: # do something 559: if (( i > 5 )) ; then 560: 561: }}} 562: 563: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Compare exit code using arithmetic expressions expressions 564: 565: Use POSIX arithmetic expressions to test for exit/return codes of commands and functions. For example turn 566: 567: {{{ 568: 569: if [ $? -gt 0 ] ; then 570: 571: }}} 572: 573: into 574: 575: {{{ 576: 577: if (( $? > 0 )) ; then 578: 579: }}} 580: 581: ==== [[image:images/tag_bourne.png||alt="[Bourne]"height=""]] Use builtin commands in conditions for {{code}}while{{/code}} endless loops 582: 583: Make sure that your shell has a "{{code}}true{{/code}}" builtin (like ksh93) when executing endless loops like {{code}}$ while true ; do do_something ; done #{{/code}} - otherwise each loop cycle runs a {{code}}|fork()|+|exec()|{{/code}}-cycle to run {{code}}/bin/true{{/code}} 584: 585: ==== Single-line if-statements 586: 587: It is permissible to use {{code}}&&{{/code}} and {{code}}||{{/code}} to construct shorthand for an "{{code}}if{{/code}}" statement in the case where the if statement has a single consequent line: 588: 589: {{{ 590: 591: [ $# -eq 0 ] && exit 0 592: 593: }}} 594: 595: instead of the longer: 596: 597: {{{ 598: 599: if [ $# -eq 0 ]; then 600: exit 0 601: fi 602: 603: }}} 604: 605: ==== Exit Status and {{code}}if{{/code}}/{{code}}while{{/code}} statements 606: 607: Recall that "{{code}}if{{/code}}" and "{{code}}while{{/code}}" operate on the exit status of the statement to be executed. In the shell, zero (0) means true and non-zero means false. The exit status of the last command which was executed is available in the $? variable. When using "{{code}}if{{/code}}" and "{{code}}while{{/code}}", it is typically not necessary to use {{code}}$?{{/code}} explicitly, as in: 608: 609: {{{ 610: 611: grep foo /etc/passwd >/dev/null 2>&1 612: if [ $? -eq 0 ]; then 613: echo "found" 614: fi 615: 616: }}} 617: 618: Instead, you can more concisely write: 619: 620: {{{ 621: 622: if grep foo /etc/passwd >/dev/null 2>&1; then 623: echo "found" 624: fi 625: 626: }}} 627: 628: Or, when appropriate: 629: 630: {{{ 631: 632: grep foo /etc/passwd >/dev/null 2>&1 && echo "found" 633: 634: }}} 635: 636: === Variable types, naming and usage 637: 638: ==== Names of local, non-environment, non-constant variables should be lowercase 639: 640: Names of variables local to the current script which are not exported to the environment should be lowercase while variable names which are exported to the environment should be uppercase. 641: 642: The only exception are global constants (=global readonly variables, e.g. {{code}}$ float -r M_PI=3.14159265358979323846 #{{/code}} (taken from <math.h>)) which may be allowed to use uppercase names, too. 643: 644: === Warning 645: 646: Uppercase variable names should be avoided because there is a good chance of naming collisions with either special variable names used by the shell (e.g. {{code}}PWD{{/code}}, {{code}}SECONDS{{/code}} etc.). 647: 648: ==== Do not use variable names which are reserved keywords/variable names in C/C++/JAVA or the POSIX shell standard 649: 650: Do not use variable names which are reserved keywords in C/C++/JAVA or the POSIX shell standard (to avoid confusion and/or future changes/updates to the shell language). 651: 652: === Note 653: 654: The Korn Shell and the POSIX shell standard have many more reserved variable names than the original Bourne shell. All these reserved variable names are spelled uppercase. 655: 656: ==== Always use {{code}}’{’{{/code}}+{{code}}’}’{{/code}} when using variable names longer than one character 657: 658: Always use {{code}}’{’{{/code}}+{{code}}’}’{{/code}} when using variable names longer than one character unless a simple variable name is followed by a blank, {{code}}/{{/code}}, {{code}};{{/code}}, or {{code}}${{/code}} character (to avoid problems with array, compound variables or accidental misinterpretation by users/shell) 659: 660: {{{ 661: 662: print "$foo=info" 663: 664: }}} 665: 666: should be rewritten to 667: 668: {{{ 669: 670: print "${foo}=info" 671: 672: }}} 673: 674: ==== //Always// put variables into quotes when handling filenames or user input 675: 676: //Always// put variables into quotes when handling filenames or user input, even if the values are hardcoded or the values appear to be fixed. Otherwise at least two things may go wrong: 677: 678: * a malicious user may be able to exploit a script’s inner working to infect his/her own code 679: * a script may (fatally) misbehave for unexpected input (e.g. file names with blanks and/or special symbols which are interpreted by the shell) 680: 681: === Note 682: 683: As alternative a script may set {{code}}IFS=’’ ; set -o noglob{{/code}} to turn off the interpretation of any field seperators and the pattern globbing. 684: 685: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use typed variables if possible. 686: 687: For example the following is very inefficient since it transforms the integer values to strings and back several times: 688: 689: {{{ 690: 691: a=0 692: b=1 693: c=2 694: # more code 695: if [ $a -lt 5 -o $b -gt c ] ; then do_something ; fi 696: 697: }}} 698: 699: This could be rewritten using ksh constructs: 700: 701: {{{ 702: 703: integer a=0 704: integer b=1 705: integer c=2 706: # more code 707: if (( a < 5 || b > c )) ; then do_something ; fi 708: 709: }}} 710: 711: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Store lists in arrays or associative arrays 712: 713: Store lists in arrays or associative arrays - this is usually easier to manage. 714: 715: For example: 716: 717: {{{ 718: 719: x=" 720: /etc/foo 721: /etc/bar 722: /etc/baz 723: " 724: echo $x 725: 726: }}} 727: 728: can be replaced with 729: 730: {{{ 731: 732: typeset -a mylist 733: mylist[0]="/etc/foo" 734: mylist[1]="/etc/bar" 735: mylist[2]="/etc/baz" 736: print "${mylist[@]}" 737: 738: }}} 739: 740: or (ksh93-style append entries to a normal (non-associative) array) 741: 742: {{{ 743: 744: typeset -a mylist 745: mylist+=( "/etc/foo" ) 746: mylist+=( "/etc/bar" ) 747: mylist+=( "/etc/baz" ) 748: print "${mylist[@]}" 749: 750: }}} 751: 752: === Difference between expanding arrays with mylist[@] and mylist[*] subscript operators 753: 754: Arrays may be expanded using two similar subscript operators, @ and *. These subscripts differ only when the variable expansion appears within double quotes. If the variable expansion is between double-quotes, "${mylist[*]}" expands to a single string with the value of each array member separated by the first character of the {{code}}IFS{{/code}} variable, and "${mylist[@]}" expands each element of name to a separate string. 755: 756: **Example�2.�Difference between [@] and [*] when expanding arrays** 757: 758: {{{ 759: 760: typeset -a mylist 761: mylist+=( "/etc/foo" ) 762: mylist+=( "/etc/bar" ) 763: mylist+=( "/etc/baz" ) 764: IFS="," 765: printf "mylist[*]={ 0=|%s| 1=|%s| 2=|%s| 3=|%s| }\n" "${mylist[*]}" 766: printf "mylist[@]={ 0=|%s| 1=|%s| 2=|%s| 3=|%s| }\n" "${mylist[@]}" 767: 768: }}} 769: 770: will print: 771: 772: {{{ 773: 774: mylist[*]={ 0=|/etc/foo,/etc/bar,/etc/baz| 1=|| 2=|| 3=|| } 775: mylist[@]={ 0=|/etc/foo| 1=|/etc/bar| 2=|/etc/baz| 3=|| } 776: 777: }}} 778: 779: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use compound variables or associative arrays to group similar variables together 780: 781: Use compound variables or associative arrays to group similar variables together. 782: 783: For example: 784: 785: {{{ 786: 787: box_width=56 788: box_height=10 789: box_depth=19 790: echo "${box_width} ${box_height} ${box_depth}" 791: 792: }}} 793: 794: could be rewritten to ("associative array"-style) 795: 796: {{{ 797: 798: typeset -A -E box=( [width]=56 [height]=10 [depth]=19 ) 799: print ~-- "${box[width]} ${box[height]} ${box[depth]}" 800: 801: }}} 802: 803: or ("compound variable"-style 804: 805: {{{ 806: 807: box=( 808: float width=56 809: float height=10 810: float depth=19 811: ) 812: print ~-- "${box.width} ${box.height} ${box.depth}" 813: 814: }}} 815: 816: === I/O 817: 818: ==== Avoid using the "{{code}}echo{{/code}}" command for output 819: 820: The behaviour of "{{code}}echo{{/code}}" is not portable (e.g. System V, BSD, UCB and ksh93/bash shell builtin versions all slightly differ in functionality) and should be avoided if possible. POSIX defines the "{{code}}printf{{/code}}" command as replacement which provides more flexible and portable behaviour. 821: 822: === [[image:images/tag_ksh.png||alt="[ksh]"height=""]] Use "{{code}}print{{/code}}" and not "{{code}}echo{{/code}}" in Korn Shell scripts 823: 824: Korn shell scripts should prefer the "{{code}}print{{/code}}" builtin which was introduced as replacement for "{{code}}echo{{/code}}". 825: 826: === Caution 827: 828: Use {{code}}$ print ~-- ${varname}" #{{/code}} when there is the slightest chance that the variable "{{code}}varname{{/code}}" may contain symbols like "-". Or better use "{{code}}printf{{/code}}" instead, for example 829: 830: {{{ 831: 832: integer fx 833: # do something 834: print $fx 835: 836: }}} 837: 838: may fail if "f" contains a negative value. A better way may be to use 839: 840: {{{ 841: 842: integer fx 843: # do something 844: printf "%d\n" fx 845: 846: }}} 847: 848: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}redirect{{/code}} and not {{code}}exec{{/code}} to open files 849: 850: Use {{code}}redirect{{/code}} and not {{code}}exec{{/code}} to open files - {{code}}exec{{/code}} will terminate the current function or script if an error occurs while {{code}}redirect{{/code}} just returns a non-zero exit code which can be caught. 851: 852: Example: 853: 854: {{{ 855: 856: if redirect 5</etc/profile ; then 857: print "file open ok" 858: head <&5 859: else 860: print "could not open file" 861: fi 862: 863: }}} 864: 865: ==== [[image:images/tag_perf.png||alt="[perf]"height=""]] Avoid redirections per command when the output goes into the same file, e.g. {{code}}$ echo "foo" >xxx ; echo "bar" >>xxx ; echo "baz" >>xxx #{{/code}} 866: 867: Each of the redirections above trigger an {{code}}|open()|,|write()|,|close()|{{/code}}-sequence. It is much more efficient (and faster) to group the rediction into a block, e.g. {{code}}{ echo "foo" ; echo "bar" ; echo "baz" } >xxx #{{/code}} 868: 869: ==== [[image:images/tag_perf.png||alt="[perf]"height=""]] Avoid the creation of temporary files and store the values in variables instead 870: 871: Avoid the creation of temporary files and store the values in variables instead if possible 872: 873: Example: 874: 875: {{{ 876: 877: ls -1 >xxx 878: for i in $(cat xxx) ; do 879: do_something ; 880: done 881: 882: }}} 883: 884: can be replaced with 885: 886: {{{ 887: 888: x="$(ls -1)" 889: for i in ${x} ; do 890: do_something ; 891: done 892: 893: }}} 894: 895: === Note 896: 897: ksh93 supports binary variables (e.g. {{code}}typeset -b varname{{/code}}) which can hold any value. 898: 899: ==== If you create more than one temporary file create an unique subdir 900: 901: If you create more than one temporary file create an unique subdir for these files and make sure the dir is writable. Make sure you cleanup after yourself (unless you are debugging). 902: 903: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {n}<file instead of fixed file descriptor numbers 904: 905: When opening a file use {n}<file, where {{code}}n{{/code}} is an integer variable rather than specifying a fixed descriptor number. 906: 907: This is highly recommended in functions to avoid that fixed file descriptor numbers interfere with the calling script. 908: 909: **Example�3.�Open a network connection and store the file descriptor number in a variable** 910: 911: {{{ 912: 913: function cat_http 914: { 915: integer netfd 916: 917: ... 918: 919: # open TCP channel 920: redirect {netfd}<>"/dev/tcp/${host}/${port}" 921: 922: # send HTTP request 923: request="GET /${path} HTTP/1.1\n" 924: request+="Host: ${host}\n" 925: request+="User-Agent: demo code/ksh93 (2007-08-30; $(uname -s -r -p))\n" 926: request+="Connection: close\n" 927: print "${request}\n" >&${netfd} 928: 929: # collect response and send it to stdout 930: cat <&${netfd} 931: 932: # close connection 933: exec {netfd}<&- 934: 935: ... 936: 937: } 938: 939: }}} 940: 941: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use inline here documents instead of {{code}}echo "$x" | command{{/code}} 942: 943: Use inline here documents, for example 944: 945: {{{ 946: 947: command <<< $x 948: 949: }}} 950: 951: rather than 952: 953: {{{ 954: 955: print -r ~-- "$x" | command 956: 957: }}} 958: 959: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use the {{code}}-r{{/code}} option of {{code}}read{{/code}} to read a line 960: 961: Use the {{code}}-r{{/code}} option of {{code}}read{{/code}} to read a line. You never know when a line will end in {{code}}\{{/code}} and without a {{code}}-r{{/code}} multiple lines can be read. 962: 963: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Print compound variables using {{code}}print -C varname{{/code}} or {{code}}print -v varname{{/code}} 964: 965: Print compound variables using {{code}}print -C varname{{/code}} or {{code}}print -v varname{{/code}} to make sure that non-printable characters are correctly encoded. 966: 967: **Example�4.�Print compound variable with non-printable characters** 968: 969: {{{ 970: 971: compound x=( 972: a=5 973: b="hello" 974: c=( 975: d=9 976: e="$(printf "1\v3")" [[image:images/callouts/1.png||alt="1"height=""]] 977: ) 978: ) 979: print -v x 980: 981: }}} 982: 983: will print: 984: 985: {{{ 986: 987: ( 988: a=5 989: b=hello 990: c=( 991: d=9 992: e=$’1\0133’ [[image:images/callouts/1.png||alt="1"height=""]] 993: ) 994: ) 995: 996: }}} 997: 998: |[[[[image:images/callouts/1.png||alt="1"height=""]]>>#co.vertical_tab1]] [[[[image:images/callouts/1.png||alt="1"height=""]]>>#co.vertical_tab2]]| 999: vertical tab, {{code}}\v{{/code}}, octal={{code}}\013{{/code}}. 1000: 1001: ==== Put the command name and arguments before redirections 1002: 1003: Put the command name and arguments before redirections. You can legally do {{code}}$ > file date{{/code}} instead of {{code}}date > file{{/code}} but don’t do it. 1004: 1005: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Enable the {{code}}gmacs{{/code}} editor mode when reading user input using the {{code}}read{{/code}} builtin 1006: 1007: Enable the {{code}}gmacs{{/code}}editor mode before reading user input using the {{code}}read{{/code}} builtin to enable the use of cursor+backspace+delete keys in the edit line 1008: 1009: **Example�5.�Prompt user for a string with gmacs editor mode enabled** 1010: 1011: {{{ 1012: 1013: set -o gmacs [[image:images/callouts/1.png||alt="1"height=""]] 1014: typeset inputstring="default value" 1015: ... 1016: read -v[[image:images/callouts/2.png||alt="2"height=""]] inputstring[[image:images/callouts/3.png||alt="3"height=""]]?"Please enter a string: "[[image:images/callouts/4.png||alt="4"height=""]] 1017: ... 1018: printf "The user entered the following string: ’%s’\n" "${inputstring}" 1019: 1020: ... 1021: 1022: }}} 1023: 1024: |[[[[image:images/callouts/1.png||alt="1"height=""]]>>#co.enable_gmacs]]| 1025: Enable gmacs editor mode. 1026: |[[[[image:images/callouts/2.png||alt="2"height=""]]>>#co.read_v]]| 1027: The value of the variable is displayed and used as a default value. 1028: |[[[[image:images/callouts/3.png||alt="3"height=""]]>>#co.readvar]]| 1029: Variable used to store the result. 1030: |[[[[image:images/callouts/4.png||alt="4"height=""]]>>#co.prompt]]| 1031: Prompt string which is displayed in stderr. 1032: 1033: === Math 1034: 1035: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Use builtin arithmetic expressions instead of external applications 1036: 1037: Use builtin (POSIX shell) arithmetic expressions instead of {{code}}expr{{/code}}, {{code}}bc{{/code}}, {{code}}dc{{/code}}, {{code}}awk{{/code}}, {{code}}nawk{{/code}} or {{code}}perl{{/code}}. 1038: 1039: === Note 1040: 1041: ksh93 supports C99-like floating-point arithmetic including special values such as +Inf, -Inf, +NaN, -NaN. 1042: 1043: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use floating-point arithmetic expressions if calculations may trigger a division by zero or other exceptions 1044: 1045: Use floating-point arithmetic expressions if calculations may trigger a division by zero or other exceptions - floating point arithmetic expressions in ksh93 support special values such as {{code}}+Inf{{/code}}/{{code}}-Inf{{/code}} and {{code}}+NaN{{/code}}/{{code}}-NaN{{/code}} which can greatly simplify testing for error conditions, e.g. instead of a {{code}}trap{{/code}} or explicit {{code}}if ... then... else{{/code}} checks for every sub-expression you can check the results for such special values. 1046: 1047: Example: 1048: 1049: {{{ 1050: 1051: $ **{{code}}ksh93 -c ’integer i=0 j=5 ; print ~-- "x=$((j/i)) "’{{/code}}** 1052: ksh93: line 1: j/i: divide by zero 1053: $ **{{code}}ksh93 -c ’float i=0 j=-5 ; print ~-- "x=$((j/i)) "’{{/code}}** 1054: x=-Inf 1055: 1056: }}} 1057: 1058: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Use {{code}}printf "%a"{{/code}} when passing floating-point values 1059: 1060: Use {{code}}printf "%a"{{/code}} when passing floating-point values between scripts or as output of a function to avoid rounding errors when converting between bases. 1061: 1062: Example: 1063: 1064: {{{ 1065: 1066: function xxx 1067: { 1068: float val 1069: 1070: (( val=sin(5.) )) 1071: printf "%a\n" val 1072: } 1073: float out 1074: (( out=$(xxx) )) 1075: xxx 1076: print ~-- $out 1077: 1078: }}} 1079: 1080: This will print: 1081: 1082: {{{ 1083: 1084: -0.9589242747 1085: -0x1.eaf81f5e09933226af13e5563bc6p-01 1086: 1087: }}} 1088: 1089: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Put constant values into readonly variables 1090: 1091: Put constant values into readonly variables 1092: 1093: For example: 1094: 1095: {{{ 1096: 1097: float -r M_PI=3.14159265358979323846 1098: 1099: }}} 1100: 1101: or 1102: 1103: {{{ 1104: 1105: float M_PI=3.14159265358979323846 1106: readonly M_PI 1107: 1108: }}} 1109: 1110: ==== [[image:images/tag_ksh.png||alt="[ksh]"height=""]] [[image:images/tag_perf.png||alt="[perf]"height=""]] Avoid string to number (and/or number to string) conversions in arithmetic expressions expressions 1111: 1112: Avoid string to number and/or number to string conversions in arithmetic expressions expressions to avoid performance degradation and rounding errors. 1113: 1114: **Example�6.�(( x=$x*2 )) vs. (( x=x*2 ))** 1115: 1116: {{{ 1117: 1118: float x 1119: ... 1120: (( x=$x*2 )) 1121: 1122: }}} 1123: 1124: will convert the variable "x" (stored in the machine’s native {{code}}|long double|{{/code}} datatype) to a string value in base10 format, apply pattern expansion (globbing), then insert this string into the arithmetic expressions and parse the value which converts it into the internal |long double| datatype format again. This is both slow and generates rounding errors when converting the floating-point value between the internal base2 and the base10 representation of the string. 1125: 1126: The correct usage would be: 1127: 1128: {{{ 1129: 1130: float x 1131: ... 1132: (( x=x*2 )) 1133: 1134: }}} 1135: 1136: e.g. omit the ’$’ because it’s (at least) redundant within arithmetic expressions. 1137: 1138: **Example�7.�x=$(( y+5.5 )) vs. (( x=y+5.5 ))** 1139: 1140: {{{ 1141: 1142: float x 1143: float y=7.1 1144: ... 1145: x=$(( y+5.5 )) 1146: 1147: }}} 1148: 1149: will calculate the value of {{code}}y+5.5{{/code}}, convert it to a base-10 string value amd assign the value to the floating-point variable {{code}}x{{/code}} again which will convert the string value back to the internal |long double| datatype format again. 1150: 1151: The correct usage would be: 1152: 1153: {{{ 1154: 1155: float x 1156: float y=7.1 1157: ... 1158: (( x=y+5.5 )) 1159: 1160: }}} 1161: 1162: i.e. this will save the string conversions and avoid any base2~-->base10~-->base2-conversions. 1163: 1164: ==== [[image:images/tag_ksh93.png||alt="[ksh93]"height=""]] Set {{code}}LC_NUMERIC{{/code}} when using floating-point constants 1165: 1166: Set {{code}}LC_NUMERIC{{/code}} when using floating-point constants to avoid problems with radix-point representations which differ from the representation used in the script, for example the {{code}}de_DE.*{{/code}} locale use ’,’ instead of ’.’ as default radix point symbol. 1167: 1168: For example: 1169: 1170: {{{ 1171: 1172: # Make sure all math stuff runs in the "C" locale to avoid problems with alternative 1173: # radix point representations (e.g. ’,’ instead of ’.’ in de_DE.*-locales). This 1174: # needs to be set _before_ any floating-point constants are defined in this script) 1175: if [[ "${LC_ALL}" != "" ]] ; then 1176: export \ 1177: LC_MONETARY="${LC_ALL}" \ 1178: LC_MESSAGES="${LC_ALL}" \ 1179: LC_COLLATE="${LC_ALL}" \ 1180: LC_CTYPE="${LC_ALL}" 1181: unset LC_ALL 1182: fi 1183: export LC_NUMERIC=C 1184: ... 1185: float -r M_PI=3.14159265358979323846 1186: 1187: }}} 1188: 1189: === Note 1190: 1191: The environment variable {{code}}LC_ALL{{/code}} always overrides all other {{code}}LC_*{{/code}} variables, including {{code}}LC_NUMERIC{{/code}}. The script should always protect itself against custom {{code}}LC_NUMERIC{{/code}} and {{code}}LC_ALL{{/code}} values as shown in the example above. 1192: 1193: === Misc 1194: 1195: ==== Put {{code}}[${LINENO}]{{/code}} in your {{code}}PS4{{/code}} 1196: 1197: Put {{code}}[${LINENO}]{{/code}} in your {{code}}PS4{{/code}} prompt so that you will get line numbers with you run with {{code}}-x{{/code}}. If you are looking at performance issues put {{code}}$SECONDS{{/code}} in the {{code}}PS4{{/code}} prompt as well.
Search
Collectives
Community Group
Academic and Research
Accessibility
Advocacy
Appliances
Approachability
Architecture Process and Tools
BrandZ
Chinese Users
Community Advisory Board
Databases
Desktop
Device Drivers
Distribution
Documentation
DTrace
Emerging Platforms
Fault Management
Games on OpenSolaris
HA Clusters
HPC Developer
Installation and Packaging
Internationalization and Localization
Laptop
Logical Domains
Modular Debugger (MDB)
Networking
NFS
Observability
OpenSolaris Governing Board (OGB)
OpenSolaris Printing
OS/Net (ON)
Performance
Power Management
PowerPC
Security
Service Management Facility (smf(5))
Software Porters
Solaris Volume Manager
Storage
Systems Administration Community Group
Testing
Tools Home
Unix File Systems (UFS)
Website Community
X Window System
Xen
ZFS
Zones
Project
ADSL Modem Enhancement
ARC Process Definition
ARM Platform Port
Automatic Data Migration
BIND Update
Bluetooth Stack & Drivers
Brocade FC HBA - Initiator
Brocade FC HBA - Target
Brussels - unified network link configuration
Caiman, Solaris Install Revisited
Celeste
Český portál
Chime Visualization Tool for DTrace
CIFS client for Solaris
CIFS Server
Clearview: Network Interface Coherence
Cluster Agent: Informix Dynamic Server
Cluster Agent: OpenSolaris Container
Cluster Agent: OpenSolaris xVM
Cluster Agent: Oracle E-Business Suite
Cluster agent: PostgreSQL
Cluster Agent: Samba
Cluster Agent: Tomcat
CMT
Coarse Data Flow Parallelism
Colorado: Open HA Cluster on OpenSolaris
Command Assistant
Common Array Manager
Companion - /opt/sfw: Free and Open Source software
COMSTAR: Common Multiprotocol SCSI Target
Content
Contest
CPU Observability
Credentials Process Groups
Crossbow: Network Virtualization and Resource Control
Crypto KMS Agent Toolkit
Cryptographic Framework
Data Migration Manager
Data Tethers
Deutsches Portal
Device Detection Tool
Device Driver Utility
Device Manager
Device Mapper
Direct Rendering Infrastructure & 3D drivers
DTrace Guide
Duckwater: Simplified name services management
Easy Tools
Emancipation
Emulex Fibre Channel Device Driver
Emulex Advanced Ethernet Device Driver
Enable/Enhance Solaris support for Intel Platform
Enhance the support of USB webcams
Enhanced SMF Profiles
Enhancements for AMD-based Platforms
Erlang DTrace Integration
Ethernet bridge module for Solaris
Evaluate Conary
Events Registry
Ext3 file system support
F/OSS Package Base
Facilitation
Fibre Channel over Ethernet
Fine Grained Access Policy (FGAP)
Fingerprint Authentication
Flexible Mandatory Access Control
Forensic Tools
Fully Open X Project
Fuse on Solaris
gcore
Generic Machine Check Architecture Improvements
Google SOC
HA-JBoss
HA-MySQL
Hadoop Live CD
Hitachi
HoneyComb Fixed Content Storage
HPC Stack
Image Packaging System
Improved Performance MIB
Indiana
Innovation Awards
Input Method
Intel Graphics
Internet Key Exchange, version 2
Interrupt Resource Management
IP Datapath Refactoring
IP over Infiniband
IPsec Tunnel Reform
iSCSI Extensions for Remote DMA (iSER)
iSNS Server
JeOS - Just enough Operating System
JKstat - a java binding for libkstat
Journaled File System (JFS)
K Desktop Environment
Kerberos
Kernel Sockets
Kernel SSL Enhancements
Key Management Framework
Korn Shell 93 integration/migration project
Labeled IPsec
LatencyTOP
Layer 2 Filtering
LDoms Manager
Lending
libMicro - portable microbenchmarks
Link Layer Discovery
Live Media: Technologies for distributions running from CD and other media
Locale Data
lofi compression and cryptography support
lx64 brand
Media Management System
Mega_sas
Mexico
MilaX minimal Live Distribution
MIPS Platform Port
Mozilla DTrace
MRSL.NONsharedDevice
Multi-lingual Glossary
Multi-pathing software (MPxIO)
Multiple disk sector size support
Multiple DOI
Muskoka: An open repository for OpenSolaris technical content
Navigator
Nemo: A Framework for High-Performance Networking
Network Auto-Magic
Network Data Management Protocol
Network MIBs
Network Performance Projects
Network Storage
Network Time Protocol (NTP)
Nevada Globalization
New Design of 4over6 Mechanism Based on OpenSolaris
NFS RDMA transport update and performance analysis
NFS Server in non-Global Zones
NFS version 4.1 pNFS
NFSv4 namespace extensions
Nightingale: Port Songbird to OpenSolaris
NPort ID Virtualization (NPIV)
NUMA
Object Storage Device (OSD) support for Solaris
OHACGE Script Based Plug-in
ON/Nevada (ONNV) Project
Open Development Infrastructure
Open HA Cluster Utilities
Open Sound System
OpenGrok
OpenPegasus CIM Server
OpenRTI
OpenSolaris Busybox
OpenSolaris Desktop
OpenSolaris Hispano
OpenSolaris Security Audit
OpenSolaris support for the QEMU processor emulator: host and guest
PEF: Packet Event Framework
Performance Wrappers
Pkgfactory
Polski Portal
Portail Francophone
Portal Brasil
Portals
Power Management Usability Interfaces
Presto: Automatic Printing Configuration
Printable Many Page Solaris Manuals
Promise SuperTrak RAID HBA Driver
QLogic Converged Network Adapter GLDv3 NIC Driver
Quagga Routing Protocol Suite Integration
RAID Configuration Utility
RBridge (IETF TRILL) support
RDMA Offload Framework
Reno: Login Process Enhancements for Interop
Resource Management
s10brand
SAM/QFS
SCM Migration Project
SCSI RDMA Protocol
SDcard Drivers
Sensor Abstraction Layer
Session Initiation Protocol
SFW
Shell: bourne shell, korn shell, C shell, etc.
Sierra: Intel WiFi Chipsets Support
Simple Panels
SM-HBA Based SAS HBA Management
SMF Documentation
Solaris iSCSI Target
Solaris PowerPC Port
SourceJuicer
Sparks: name service switch/nscd enhancements
Squashfs
Star integration/migration project
Starfish
Starter Kit
Storage Power Management
Sun Security Toolkit
Sun StorageTek Availability Suite
Support for OpenFabrics User Verbs / API on OpenSolaris OS
Support gcc4/GCCfss in Solaris
Suspend/Resume
SVR4 Packaging
Systemz
Tamarack: Removable Media Enhancements in Solaris
Tesla: OpenSolaris Enhanced Power Management
Test Development
Tickless Kernel Architecture
TIPC
Trademarks
Trusted networking interface policy database for Trusted Extensions
Trusted Platform Module support
Use Case
Validated Execution Project
Virtual Console
Virtual Network Machines
Visual Panels
Visualization for HPC
Volo
VRRP: Virtual Router Redundancy Protocol Implementation
VSCAN service
Web Stack
Website
Winchester: Schema mapping and ID mapping for AD Interoperability
Wireless USB Support
Wireless Wide Area Network
X Consolidation
x86 Generic FMA Topology Enumerator
Xen Gate
Xfce: A lightweight desktop environment
ZFS Boot and Install
ZFS on disk encryption support
Zone Manager
Zone Statistics
Русский портал
البوابة العربية
भारतीय पोर्टल
中国门户
日本ポータル
한국 포탈
User Group
Adelaide
Argentina
Arizona
Atlanta
Baltimore-Washington
Bangalore
Bangkok
Bangladesh
Beijing
Bélem
Berlin
Bhimavaram
Bloomington
Campus Ambassadors
Capital Region
Cardiff
Ceara
Charlotte
Chengdu
Chennai
Chihuahua
Chile
Cleveland
Colombia
Columbus
Connecticut
Cracow
Czech
Dallas/Ft. Worth
Danish
Delaware
Edinburgh
Egypt
Finland
Florida
Front Range
FuZhou
Great Lakes
Greece
Hangzhou
Hawaii
HeFei
Houston
Hong Kong
Hyderabad
Indonesia
Irish
Israel
Italian
Jinan
Jogja
Kabul
Kansas City
Latvia
London
Madurai
Manchester
Mato Grosso
Melbourne
Minas Gerais
Minnesota
Montreal
Moscow
Mumbai
Munich
NEA
Netherlands
New England
New York City
New Zealand
NIT Hamirpur
Noroeste
Nuremberg-Erlangen
Oklahoma City
Osnabrück
Peru
Philadelphia
Piaski
Pittsburgh
Porto Alegre
Puget Sound
Pune
Queensland
Rio de Janeiro
Research Triangle Park
Romania
Russia
San Antonio
San Diego
San Francisco
São Paulo
Scottish
Serbia
Shanghai
Shenzhen
Silicon Valley
Singapore
Slovak
South African
Southern Connecticut
St. Louis
Stavanger
Sweden
Switzerland
Sydney
Szczecin
Taiwan
Tecum
Thames Valley
Tokyo
Toronto
Trondheim
Tulsa
Turkey
Ufa
Ukraine
University of Melbourne
Vale do Paraíba
Vancouver
Venezuela
Welsh - Cymru
Wisconsin
Xi'an
Subsites
Code Reviews
Code Repositories
Package Search
Bugster
Bugzilla
Test Machines
Planet
Mailing Lists
Elections & Polls
ARC Case Logs
Source Juicer
Package Factory
User Authentication
Project shell Pages
Shell coding style guidelines


Dear Faculty and Staff:
As you know, in-person Commencement ceremonies are not being held due to the COVID-19 pandemic. We are still optimistic that we might be able to hold a physical ceremony in the fall, and we will keep you posted as we learn more about the reopening of New York State. We know that having a traditional ceremony would mean a lot to you, our students, and their families, and we will do our best to make it happen – if we can do it safely.
Although Commencement is postponed, many students requested caps and gowns for their personal celebrations or portraits. Purchase information may be found on the CSI Commencement webpage.
Many students have also asked about diplomas. We are pleased to announce that we can mail diplomas to our June and August graduates. More information regarding when graduates may expect their diplomas in the mail will be forthcoming, including how to access a free PDF version. For those who received their degrees in January, we are currently working on getting their diplomas to them.
Please know that we are excited to honor our graduates. Beginning May 26, 2020, we are going to start celebrating our graduates. Please follow CSI on Facebook, Instagram, and/or Twitter to see our social media campaign. We will also list the names of candidates for graduation on the CSI Commencement webpage and in the Staten Island Advance (special June edition).
Finally, we will be releasing a Salute to the Class of 2020 video on May 28, 2020. CSI created this video to share our messages of congratulations and best wishes, including special messages from President William J. Fritz and the outgoing Student Government President and Class of 2020 graduate, Fatu Amara.
We know this is not the way our students planned to end their collegiate experience, and we understand their disappointment. However, we will have a Commencement celebration in the fall, and we look forward to giving our students the sendoff they deserve.
Sincerely,
Jennifer S Borrero, J.D. Vice President for Student Affairs and Alumni Engagement


From the Central Train Station in Linz take tram line 3 out of town in direction "Trauner Kreuzung" or line 4 out of town in direction "Schloß Traun" till "Plus City" (16 minutes).
Our sponsor Guid.New has organized a bus service from Graz Murpark to Hollywood Megaplex. Please register to get a seat.
The Hollywood Megaplex Pasching is located within the shopping center "Plus City" which provides free parking.


Greta Thunberg sets sail for Madrid's COP25 on a catamaran
by Euronews"We sail for home!" Greta Thunberg announced on Twitter on Wednesday.
The 16-year-old climate activist is sailing to Madrid from Virginia in the US to attend the COP25 climate conference in Spain, which starts in December.
Thunberg is on a 48ft catamaran called La Vagabonde, with an Australian couple who are travelling the world with their newborn child by boat and posting about their experience on YouTube.
Thunberg has been touring the US and meeting with climate activist groups across North America since August. She arrived in New York on another sailboat which had given her a carbon-neutral lift from Europe.
READ MORE: Watch: Greta Thunberg sails into New York for UN climate change summits
She has been to several US states including New York, California, North Dakota, Iowa, Virginia, each Friday joining the Youth for Climate Friday marches in the city she was in, while also appearing on national TV, giving speeches at the U.N., and meeting with celebrities and public figures involved in the climate movement.
She refuses to fly to protest the high level of CO2 produced by commercial flights, which greatly contributes to climate change.
Thunberg had originally planned to stay in America much longer, slowly making her way to South America, where Chile was expected to host the COP25 meeting.
But after a wave of protests erupted in the Chilean capital, Santiago, the country announced that it could no longer host the talks, and Spain offered Madrid as an alternative venue.
This left Thunberg in need of a boat ride back to Europe.
"It turns out I've traveled half around the world, the wrong way", she tweeted, adding: "If anyone could help me find transport I would be so grateful."


As we can see, the client starts with a suggestion of security protocols to use for the RDP session. Wedifferentiate these three protocols:
– Standard RDP security
– Enhanced RDP security or TLS security
– CredSSP
Note that standard RDP security is alwayspossible and does not need to be advertised by the client. TLS, or “enhanced RDP security”, is simply standardRDP security wrapped inside an encrypted TLS tunnel
An SSL handshake is performed after client and server have agreed on using enhanced RDP security, so if we want to MitM an RDP connection, we cannot simply use an SSL proxy, because the proxy needs to be aware of the RDP. It needs to recognize when to initiate the SSL handshake, similarly to StartTLS in SMTP or FTP.


Man films neighbour spraying him with hosepipe in feud over driveway
A ‘nightmare’ feud between two retired couples over their driveways has ended up in court after one pair sprayed their neighbour with a hosepipe.
Magistrates heard how Harold Burrows, 70, got soaked when he cleared up garden debris washed under his gate and tried to return it to his neighbours’ drive in Denbigh, North Wales.
He had strapped a GoPro camera to himself after years of squabbling with the pair, capturing footage which was shown in court.
Advertisement Advertisement
Barry Lee and Hellynne Lee, both 72, admitted common assault on June 4.
Prosecutor Julia Galston said Ms Lee had sprayed Mr Burrows and Mr Lee then did the same, remarking: ‘He likes getting wet, this little man.’
Ms Galston said Ms Lee called Mr Burrows’ wife Jean a ‘witch’ and him a ‘moron’.
‘The incident has had a huge effect on Mr and Mrs Burrows’, Ms Galston added.
Mr Burrows, an MBE-decorated search team volunteer and Ms Burrows, a charity shop volunteer, moved to the area 20 years ago and started having problems with the Lees over garden waste turning up in their driveway.
The neighbours resorted to police mediation, after which the Burrows were advised to install CCTV at their house, the court heard.
The slope between their adjacent properties and the Lees’ habit of cleaning their driveway with their hose rather than a brush meant ‘crud’ would flow into the Burrows’ driveway, defence solicitor Robert Vickery said.
He told the court that the property developers’ failure to follow plans when the estate was built was probably the ‘root cause’ of the feud, and the neighbours used to be friends.
He told magistrates at Llandudno: ‘You may wonder what on earth are we doing here in a criminal court dealing with that? The reason is, sadly, Mr and Mrs Lee and Mr and Mrs Burrows can’t live peacefully together and have had many, many years of aggravation between them.’
Advertisement Advertisement
Mr Vickery said Mrs Lee was wrong to spray Mr Burrows but thought there was ‘some provocation’ in light of their history.
In the clip Mr Burrows is shown dividing the debris and placing some of it on the Lees’ driveway.
Mr Vickery continued: ‘It’s just utter madness from each point of view. I don’t think anyone in this case comes out with any credit. It’s beggars belief people can’t live together’
The Lees had spent £8,500 on county court action but now plan to move, he added.
Mrs Galston added for the prosecution: ‘The Crown don’t seek to minimise this assault. It’s a nasty assault. Mr Burrows is entitled to be in his own garden without being sprayed with the hosepipe.’
Outside court Mr Burrows said: ‘It’s been a nightmare living next door. I will be glad when they sell up.’
Got a story for Metro.co.uk?
Get in touch with our news team by emailing us at<EMAIL_ADDRESS>For more stories like this, check our news page.


I truly believe we can change the way of things with what you guys are developing , I see so many projects focusing or either on TPS , or on a ICO platform , or smart contracts , how can't I beliebe when we are focusing on everything that I mentioned and much more??


- 5 min read
--- layout: default page-title: Ketch Partners page-description: Ketch Partners SAP HANA S4 Greenfield Implementation canonical: https://ketch.partners/articles/sap-greenfield-implementation/ robots: index,follow rating: og-title: Overview of SAP HANA S4 Greenfiled Implementation og-type: article og-url: https://ketch.partners/articles/sap-greenfield-implementation/ og-image: https://ketch.partners/assets/img/articles/greenfield-business-sap-800x350.jpg og-description: Ketch Partners client use case of SAP HANA S4 implementation. og-sitename: Ketch Partners fb-id: twitter-summary: Ketch Partners client use case of SAP HANA S4 greenfield implementation. twitter-handle: twitter-title: Overview of SAP HANA S4 Greenfield Implementation. twitter-description: Ketch Partners client use case overview of SAP HANA S4 greenfield implementation. twitter-author: chris_r_york twitter-image: https://ketch.partners/assets/img/articles/greenfield-business-sap-300x300.jpg datePublished: 2018-12-26 dateModified: 2018-12-26 datePublishedDisplay: 26 December 2018 ---
- 5 min read


◄ 19th WPC 2010 ►
Team results • Individual results
- General information
- Paprotnia, Poland (Home Page WPC 2010), 24.10. - 29.10. 2010
- Number of participating teams: 26.
- Number of contestants: 105.
- Instruction Booklet
- Competition Timetable
Date Time Number Type Title Duration Max points 26th October 09:30 - 09:49 Part 1 Individual Welcome 19 min 113 points 26th October ???? Part 2 Individual Classics of WPC 60 min 300 points 26th October ???? Part 3 Individual Married Puzzles 45 min 225 points 26th October 12:10 - 13:00 Part 4 Team Anaconda 50 min 900 points 26th October 14:30 - 15:30 Part 5 Individual Innovations 60 min 300 points 26th October ???? Part 6 Individual Even/Odd 45 min 225 points 26th October 16:30 - 17:00 Part 7 Team Sym-a-Pix 30 min 600 points 27th October 09:30 - 09:55 Part 8 Individual Sprint 25 min 125 points 27th October ???? Part 9 Individual Assorted 90 min 450 points 27th October ???? Part 10 Individual Spherical Operations 25 min # points 27th October ???? - 13:00 Part 11 Team Operation "Kuznia" 30 min 600 points 27th October 14:30 - 15:30 Part 12 Individual Poliomino 60 min 300 points 27th October ???? Part 13 Individual Broken Puzzles 45 min 225 points 27th October 16:20 - 17:00 Part 14 Team Slither Link = Weakest Link 40 min 800 points 28th October 09:00 - 09:15 Part 15 Individual Screen Test 15 min 114 points
# This round had been cancelled for various reasons.


Santa Claus Back at Work in Germany Answering Christmas Mail
by ASSOCIATED PRESSHIMMELPFORT, Germany (AP) — Santa Claus is at it again, answering thousands of Christmas letters from children around the world at a special post office in the northern German town of Himmelpfort.
As part of the annual event organized by Germany’s Deutsche Post, Santa and 20 helpers last year responded to 277,200 letters from 64 countries.
They answer in various languages and also in braille, and each letter has a special Santa postmark.
The tradition began when postal workers in 1984 received two letters addressed to Santa in Himmelpfort, which means “heaven’s gate.”
Not wanting to send them back “recipient unknown” they answered.
All letters received between Thursday and Dec. 15 will be personally answered and returned before Christmas.
Address letters to: An den Weihnachtsmann, Weihnachtspostfiliale, 16798, Himmelpfort, Germany. Remember a return address.
Copyright © 2019 courthousenews.com


Scrollable Div Popup External Content
The popup scrollable div is optimized for screen reader and keyboard only users:
- Activate the Show button to open the popup. The content will be inserted inline with the triggering element, and focus will automatically move to the scrollable div.
- Press Up/ Down/ Left/ Right to navigate in 30% increments.
- Press PageUp/PageDown to navigate by 90% increments.
- Press Home/End to navigate to the beginning or end of the scrollable content.
- Tab to set focus to the Close link and press Enter to close the popup, or press Escape to close the popup directly.
- When closed, focus will move back to the triggering element.


MapDrawer Class
Map drawing class - abstraction for easier use of google maps
Constructor
MapDrawer
(
-
mapElement
Parameters:
-
mapElement
ObjectHTML Element to which put the map
Item Index
Methods
Methods
drawLine
(
-
start
-
finish
-
options
Draws a line on the map
drawMarker
(
-
position
-
options
Draws a marker on the map
Parameters:
-
position
Pointposition of the marker on the map
-
options
ObjectOptions of the marker: caption, content, popup
initAnimations
()
Run line animations on the map


Dear {{client_name}}
Thank you for your interest in our company and opportunity to quote. We are pleased to quote as follows:
| Item | Price |
|---|---|
| {{name}} | ${{numberFormat price}} |
All prices quoted are valid for 30 days from the date of stated on the quotation. Where you are unsure about any of the information supplied in this quotation, please contact to discuss further as the company will work with you to explain any element you are unsure of. If you require a reasonable breakdown of your quotation please contact the company and we will try where possible to clarify the costs quoted.


-
atm.h
- External header file
-
atmInt.h
- Internal header file
-
atmMain.c
- The main file of the Atm package.
-
atmParse.c
- The file provides typechecking functions for expressions.
-
atmTypeCheck.c
- Contains routine for type checking.
-
atmUtil.c
- Provides utility functions for manipulating the data structures
in the atm package.
atm.h
External header file
By: Shaz Qadeer, Sriram Rajamani
See AlsoatmInt.h
atmInt.h
Internal header file
By: Shaz Qadeer, Sriram Rajamani
See Alsoatm.h
atmMain.c
The main file of the Atm package.
By: Sriram Rajamani, Shaz Qadeer, Freddy Mang
This file provides functions for initializing and ending the Atm
package, and for printing expressions.
See AlsoatmInt.h,
atm.h
-
Atm_Init()
- Initializes the atm package.
-
Atm_Reinit()
- Reinitializes the atm package.
-
Atm_End()
- Ends the atm package.
-
Atm_ExprPrintExpression()
- Prints the expression.
-
Atm_ExprTypeConvertToString()
- Returns the symbolic character for an expression type.
atmParse.c
The file provides typechecking functions for expressions.
By: Shaz Qadeer, Freddy Mang
Provides functions required in typechecking and for modifying
expressions so that the MDDs can be recursively built.
See AlsoAtm.h,
AtmInt.h
-
Atm_NumConstExprConvertToBitvectorConstExpr()
- Converts leaves of type Atm_NumConst_c of the expr to
Atm_BitwiseNumConst_c.
-
AtmExprReadLeftChildAddress()
-
-
AtmExprReadRightChildAddress()
-
atmTypeCheck.c
Contains routine for type checking.
By: Freddy Mang
optional
See Alsooptional
-
Atm_TypeCheckNew()
- Typecheck an expression.
-
Atm_ReinitTypeCheck()
- required
-
SOTGet()
- required
-
SOTCreate()
- required
-
SOTIsEmpty()
- Check if the given SOT is empty.
-
SOTUnion()
- required
-
SOTIntersect()
- required
-
SOTSubset()
- required
-
SOTEqual()
- required
-
SOTMinus()
- required
-
SOTDup()
- required
-
SOTAlloc()
- required
-
SOTFree()
- required
-
SOTObtainFromVar()
- required
-
SOTObtainFromExpr()
- required
-
TypeArrayObtainFromSOT()
- required
-
PrintSOT()
- required
-
TCManagerFree()
- required
-
ExprResolveTypes()
- required
-
ScalarDataTypeConvertToBitvectorDataType()
- converts an Atm datatype into its bitwise counterpart.
-
PickAType()
- Just pick a type.
-
ExprSimplify2()
- Returns a simplified expression.
-
BitArrayToNum()
- required
atmUtil.c
Provides utility functions for manipulating the data structures
in the atm package.
By: Freddy Mang, Shaz Qadeer
See AlsoatmInt.h,
atm.h
-
Atm_AtomAlloc()
- Allocates an atom.
-
Atm_AtomFree()
- Frees an atom.
-
Atm_CmdAlloc()
- Allocates a guarded command.
-
Atm_CmdFree()
- Frees a guarded command.
-
Atm_AssignStdAlloc()
- Allocates a standard assignment.
-
Atm_AssignEventAlloc()
- Allocates an event assignment.
-
Atm_AssignIndexAlloc()
- Allocates an index assignment.
-
Atm_AssignForallAlloc()
- Allocates a forall assignment.
-
Atm_AssignFree()
- Frees an assignment.
-
Atm_AtomAddInitCommandList()
- Add the given init command to the atom
-
Atm_AtomReadInitCommandList()
- Returns the list of init commands for the atom
-
Atm_AtomReadDefaultInitCommand()
- Returns the default init guarded command of the atom.
-
Atm_AtomAddUpdateCommandList()
- Add the given update command list to the atom
-
Atm_AtomReadUpdateCommandList()
- Returns the list of update commands for the atom
-
Atm_AtomReadDefaultUpdateCommand()
- Returns the default update guarded command of the atom.
-
Atm_AtomAddWaitCommandList()
- Add the given wait command list to the atom
-
Atm_AtomReadWaitCommandList()
- Returns the list of wait commands for the atom
-
Atm_AtomAddControlVar()
- Add the given variable to the controlled variable list
-
Atm_AtomReadControlVarList()
- Returns the list of control variables for the atom
-
Atm_AtomAddReadVar()
- Add the given variable to the read variable list
-
Atm_AtomReadReadVarList()
- Returns the list of read variables for the atom
-
Atm_AtomAddAwaitVar()
- Add the given variable to the await variable list
-
Atm_AtomReadAwaitVarList()
- Returns the list of await variables for the atom
-
Atm_AtomObtainReadAwaitVarList()
- Computes the set of variables that are both read and
awaited by an atom.
-
Atm_AtomObtainReadOrAwaitVarList()
- Computes the set of variables that are either read or
awaited by an atom.
-
Atm_AtomReadAtomType()
- Returns the atom type.
-
Atm_AtomSetAtomType()
- Set the atom type.
-
Atm_AtomSetDefaultInitCommand()
- Sets the default init command of atom.
-
Atm_AtomSetDefaultUpdateCommand()
- Sets the default update command of atom.
-
Atm_AtomReadName()
- Returns the name of the atom.
-
Atm_AtomNewName()
- Generates a new atom name.
-
Atm_AtomCounterReset()
- Reset the global atom counter.
-
Atm_CmdReadGuard()
- Returns the guard expression of a guarded command.
-
Atm_CmdReadAssignList()
- Returns the list of assignments of a guarded command.
-
Atm_ExprReadType()
- Returns the type of an expression.
-
Atm_ExprReadLeftChild()
- Reads the left child of an expression.
-
Atm_ExprReadRightChild()
- Reads the right child of an expression.
-
Atm_AssignReadType()
- Returns the type of an assignment.
-
Atm_AssignReadVariable()
- Returns the variable on the left hand side of the
assignment.
-
Atm_AssignReadExpr()
- Returns the expr on the right hand side of assignment.
-
Atm_AssignReadExprAddress()
- Returns the address of expr on the right hand side of assignment.
-
Atm_AssignReadIndexVar()
- Returns the index variable of a forall assignment.
-
Atm_AssignReadIndexExpr()
- Returns the index expr of an index assignment.
-
Atm_ExprAlloc()
- Build an expression from two expression and an operator.
-
Atm_ExprFreeExpression()
- Frees an expression recursively.
-
Atm_AtomReadPreorder()
- Read the preorder of the given atom.
-
Atm_AtomReadPostorder()
- Read the postorder of the given atom.
-
Atm_AtomSetPreorder()
- Set the preorder of the given atom.
-
Atm_AtomSetPostorder()
- Set the postorder of the given atom.
-
Atm_AtomChangeName()
- Changes the name of an atom.
-
Atm_AtomDup()
- Duplicate an atom.
-
Atm_ExprSubstituteConstantForDummyVar()
- Substitute a constant for the dummy variable everywhere
in an expression.
-
AtmControlVarsDup()
- Copies the ctl variables
-
AtmReadVarsDup()
- Copy the variables read by a given atom to the new atom.
-
AtmAwaitVarsDup()
- Copy the variables awaited by a given atom to the new atom.
-
AtmGuardedCommandsDup()
- Copy the guarded commands from one atom to another.
-
AtmSelectedCommandsDup()
- Copy the guarded command to the new atom.
-
AtmAssignListDup()
- Returns a copy of the assignment list.
-
AtmExprDup()
- Returns an exact duplicate of the expression tree.
Last updated on 1031104 18h39


AddPathArc()
Syntax
AddPathArc(x1.d, y1.d, x2.d, y2.d, Radius.d, [, Flags])Description
Adds a straight line towards (x1, y2) followed by an arc in the direction of (x2, y2) to the vector drawing path. This function can be used to create paths with rounded corners. The new cursor position will be the endpoint of the arc.
Parameters
x1.d, y1.d The target position for the straight line. x2.d, y2.d The target position to indicate the direction of the arc. Radius.d The radius for the rounded corner. Flags (optional) Can be one of the following values: #PB_Path_Default : The positions are absolute (default) #PB_Path_Relative: The positions are relative to the last cursor position.
Return value
None.
Remarks
The following image illustrates the meaning of the two reference points and the the segments that are added to the path. Note that no second straight line is added towards the (x2, y2) point by the command. This makes it possible to use AddPathArc() again to add a further rounded corner also at the (x2, y2) position.
Example
If OpenWindow(0, 0, 0, 400, 200, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) CanvasGadget(0, 0, 0, 400, 200) If StartVectorDrawing(CanvasVectorOutput(0)) MovePathCursor(40, 60) AddPathArc(100, 140, 160, 20, 20) AddPathArc(160, 20, 220, 180, 20) AddPathArc(220, 180, 280, 80, 20) AddPathArc(280, 80, 340, 120, 20) AddPathLine(340, 120) VectorSourceColor(RGBA(255, 0, 0, 255)) StrokePath(10) StopVectorDrawing() EndIf Repeat Event = WaitWindowEvent() Until Event = #PB_Event_CloseWindow EndIf
See Also
MovePathCursor(), AddPathLine(), AddPathCurve(), AddPathCircle(), AddPathEllipse(), AddPathBox()
Supported OS
All


Likelihood-based and Bayesian methods for various compound Poisson linear models based on Zhang, Yanwei (2013) <https://link.springer.com/article/10.1007/s11222-012-9343-7>.
| Version: | 0.7-7 |
| Depends: | R (≥ 3.2.0), coda, Matrix, splines, methods |
| Imports: | biglm, ggplot2, minqa, nlme, reshape2, statmod, stats, stats4, tweedie |
| LinkingTo: | Matrix |
| Published: | 2018-06-10 |
| Author: | Yanwei (Wayne) Zhang |
| Maintainer: | Yanwei (Wayne) Zhang <actuary_zhang at hotmail.com> |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: | https://github.com/actuaryzhang/cplm |
| NeedsCompilation: | yes |
| Citation: | cplm citation info |
| Materials: | NEWS |
| CRAN checks: | cplm results |
| Reference manual: | cplm.pdf |
| Vignettes: |
cplm |
| Package source: | cplm_0.7-7.tar.gz |
| Windows binaries: | r-devel: cplm_0.7-7.zip, r-release: cplm_0.7-7.zip, r-oldrel: cplm_0.7-7.zip |
| OS X binaries: | r-release: cplm_0.7-7.tgz, r-oldrel: cplm_0.7-7.tgz |
| Old sources: | cplm archive |
| Reverse imports: | ChainLadder, HeritSeq |
| Reverse enhances: | MuMIn |
Please use the canonical form https://CRAN.R-project.org/package=cplm to link to this page.


Theories of International Mobility and the Incorporation of Immigrants
Class 8: Mobility at Different Scales
John Palmer
Root-Oriented Policy-Making
- Identify and quantify all related values held by society
- Analyze every possible policy choice with respect to these values
- Select the set of choices that maximize the values
Branch-Oriented Policy-Making
- Focus on immediate, narrow problem and ignore related values
- Outline and compare limited alternatives and use past experience to their short-term consequences
- Select based on limited values and expected outcomes
- Repeat
- Root Method: Rational-Comprehensive
- Branch Method: Successive Limited Comparisons
Irregular Migration to EU
- Increased irregular migration to EU since 2014
- Over 1 million people crossed Mediterranean to Europe during 2015; over 3,770 died trying
- EU response has been mostly enforcement, with EU military operation in Southern Central Mediterranean and NATO operation in Eastern Mediterranean
- In fall 2015 ESI proposes a deal to get Turkey to accept rapid return of all refugees attempting to enter Greece through irregular channels.
- EU-Turkey deal announced in March 2016. Aim is to "break the business model of the smugglers" by reducing demand while also increasing costs through enforcement.
Irregular Migration to US
From Massey & Pren (2012)
From Massey & Pren (2012)
How US Enforcement Backfired
Enforcement Rational
- Neoclassical model
- Increase costs of migrating
Flaws in the rational
- New economics and social capital theory are better fit
- Long history of Mexico-US migration -- high social capital formation
- Persistent labor demand in US
- High wage differences
- Market failures in Mexico
- Long land border
Explaining U.S. Enforcement Policy
Outcomes
- End of circular migration
- Shifts in crossing points
- Strengthening of smuggler organizations
- Political feedback loop
What have US policymakers learned from this?
Trump Immigration Policy
- Statements encouraging violence and discrimination
- Muslim Ban (versions 1.0-3.0)
- Interior enforcement targeting minority communities
- Reduction in refugee resettlement
- Attempt to end DACA
- Child separation
- Family detention
- Denaturalization proceedings
- Expansion of public charge ground for inadmissibility
- Obstruction of asylum
- Talk of attempting to end birthright citizenship
- Deployment of military to border
- Use of purported "national emergency" powers to fund wall
What should EU policymakers learn from this?
Violence and Discrimination
Explaining Native Opposition
- Elite manipulation
- Prejudice driven by cultural difference
- Economic threat
Empirical Evidence
- Employers discriminate based on immigration status, religion, and origin
- Native support for immigration drops when there is increase in immigrants entering their industry and economic conditions are bad
- Threshold effects
Explaining Violence Against Immigrants
Empirical Evidence
- Hate crimes rise with unemployment rate, industrial decline, and other economic deprivation
- Direct economic competition or undermining of social norms?
- Territorial defense
- Political opportunities


All functions
|
|
compCorr
|
Fisher's Z test for comparing two correllation coefficients. |
|
fact2char
|
Coerce Factor Vector to Character Preserving Labels. |
|
fact2num
|
Coerce Factor Vector to Numeric Preserving Levels. |
|
FDButils FDButils-package
|
Utility and Convenience Functions. |
|
gcd0 gcd
|
Get greatest common divisor of two numbers. |
|
invBoxCox
|
Inverse Box-Cox Transformation. |
|
invDnorm inv_dnorm
|
Positive Inverse Of The Normal Density Function. |
|
invLogit
|
Logits To Probabilities. |
|
isEven
|
Are Elements Of x Even Numbers? |
|
isNumeral is.numeral
|
Can Character Vector Be Coerced To Numeric? |
|
isOdd
|
Are elements of x odd numbers? |
|
isWholeNumber is.wholenumber
|
Can Elements Of x Be Interpreted As Whole Numbers? |
|
latinList
|
Create Latin squares. |
|
levelOrder
|
Reorder factor levels. |
|
mahalDistC
|
Get squared Mahalanobis distances to centroid. |
|
mahalDistP
|
Get pairwise squared Mahalanobis distances. |
|
nobs
|
Number Of Non-missing Values In Vector. |
|
outliers
|
Identify potential outliers in a numeric vector. |
|
sampleMode
|
Get the sample mode of a vector or matrix. |
|
sciNot
|
Convert numeric vector to character in scientific notation. |
|
se seM
|
Standard Error Of The Mean. |
|
seP
|
Standard Error of a Proportion. |
|
series
|
Find Regular Sequences Of Integers In Numeric Vector. |


| Interface | Description |
|---|---|
| AuthenticatorFactory |
An implementation of this factory will be initialized once at startup, if the authenticator is enabled
(see
AuthenticatorFactory.getSimpleName() ). |
| AuthenticatorProvider |
| Class | Description |
|---|---|
| AuthenticationOutcomeListener<T extends com.google.protobuf.Internal.EnumLite,C extends ClientConnection,HS extends com.google.protobuf.MessageLite,HR extends com.google.protobuf.MessageLite> |
Handles SASL exchange, on the client-side.
|
| AuthenticatorProviderImpl | |
| AuthStringUtil | |
| ClientAuthenticatorProvider | |
| FastSaslClientFactory | |
| FastSaslServerFactory | |
| KerberosHelper | |
| SaslProperties | |
| SecurityConfiguration | |
| ServerAuthenticationHandler<S extends ServerConnection<S>,T extends com.google.protobuf.Internal.EnumLite> |
Handles SASL exchange, on the server-side.
|
Drill uses Java's SASL library to authenticate clients (users and other bits). This is achieved using
AuthenticationOutcomeListener
on the client-side, and
ServerAuthenticationHandler
on the server-side.
If authentication is enabled, authenticator factory
implementations are discovered at startup from scan result
using AuthenticatorProviderImpl
. At connection time, after
handshake, if either side requires authentication, a series of SASL messages are exchanged. Without successful
authentication, any subsequent messages will result in failure and connection drop.
Out of the box, Drill supports KERBEROS
(through GSSAPI) and PLAIN
(through
UserAuthenticator
) mechanisms.
Copyright © 2021 The Apache Software Foundation. All rights reserved.


Before you get going, you'll need to log in with your delicious account. There is no trick here and you don't have to worry with your personal data. Due Delicious public feed constraints, using the API was the only work-around I found in order to get things working properly.
Don't be scared, here we will just test all urls you have in your delicious account to see what is deprecated, redirected etc. Absolutely no url will be deleted or changed in any way during this step.
The process of fetching urls can take a while! Be patient and remember, you can stop the processes whenever you want.
Success 0 items found
Problem 0 items foundDuring the step2 as long as the app finds a bad url it will appears in a list below. Just click and remove. Be careful at this time, some "errors" are just timeout. Use the try it button to see by yourself if the url is good or not.


RoboUniverse Conference - Agricultural Robotics
04 Feb 2017Episode #220: Robouniverse Conference - Agricultural Robotics
I interview two speakers from the Agricultural track of the RoboUniverse 2016 conference in San Diego: Dan Harburg of Soft Robotics Inc. and Matthew Borzage of BioTac. Borzage and Harburg discuss their distinct approaches to advancing gripping technology in Agriculture. Borzage stresses the importance of tactile sensing while Harburg pushes for low cost, soft grippers with no on-board sensors.
Dan Harburg
Dan Harburg is the Director of Business Development at Soft Robotics Inc., a venture-backed startup company developing a soft end-of-arm tool for the food industry.
Matthew Borzage
Matthew Borzage is a co-founder and the Head of Business Development for SynTouch Inc.. Borzage has a background in biomedical and medical device engineering and sales.


{% include sidebar.html %} © 2018 THIRTYJIN. All rights reserved. | 由百度云提供计算服务 {% include tongji-analytics.html %}


[§454F-46] Waiver of rights. The failure of an aggrieved person to comply with sections 454F-41 and 454F-42 shall constitute a waiver of the rights contained in those sections. [L 2010, c 84, pt of §3]


Golang is awesome for developing web apps.  If we consider the entire ecosystem of web apps in Golang everything except API documentation seems
to be in place. So we have created the first API doc generator for Golang based web apps and calling it Yet
another.
FieldMap function generator for https://github.com/mholt/binding
Autobindings is a simple extention to the amazing library Binding. So binding is a reflectionless data binding
for Go's net/http. For that developer has to write a FieldMap function which is used by this library to map
the incoming JSON from the request to the struct fields.
It’s a wrapper for writing socket servers with keeping your business logic separated from the underlying
technology for sockets.
Using this we can create socket servers supporting SocketIO Server, Websocket Server, Netty based Servers, Plain
Java socket based server with a single business logic.
Is part of AppSurfer’s streaming server, where the same logic for streaming is used for websocket clients,
socket io clients, socket clients (Android SDK) and http commet clients.
DroidStalker is aimed to be an important tool for Android developer which provides a single dashboard which
shows graph about the CPU usage, Memory usage, FPS etc while testing an app.
The main reason to come up with this is, LittleEyeLabs got acquired by Facebook and they have discontinued the
product, but there is a genuine need of such a product.
Its being developed as an when we do get time in RainingClouds.
This allows different components to communicate with each other asynchronously using messaging Usecases
To allow a communication between different fragments shown in a tab to communicate with each other without any
boilerplate code
Allow communication between a service running in background and Android app
This is used in AppSurfer Android app, to update the list of applications on different tabs of the home screen
based on the categories selected in the menu bar.


API/Webhook URL
You can trigger deployments using an API request. The API url can be generated here.
Hint: Once this URL is generated it can not be restored. You should store it in a secure location. If you loose the URL you will have to generate a new one making the old URL invalid.


DATE
Sit in box knock over christmas tree, or hack up furballs. Sleep nap ears back wide eyed or hunt by meowing loudly at 5am next to human slave food dispenser, peer out window, chatter at birds, lure them to mouth purr while eating.
Make muffins plan steps for world domination. Climb leg chase dog then run away and chase laser i am the best hack up furballs. Need to chase tail ears back wide eyed for destroy couch.

Fall over dead (not really but gets sypathy) ignore the squirrels, you'll never catch them anyway yet intrigued by the shower hide when guests come over, why must they do that, and drink water out of the faucet.  Chew on cable.
Pelt around the house and up and down stairs chasing phantoms flop over scamper yet hide head under blanket so no one can see loves cheeseburgers.
Give attitude present belly, scratch hand when stroked meow so stand in front of the computer screen, and make meme, make cute face for use lap as chair i am the best.  Attack feet sun bathe, and lounge in doorway cat snacks. Intently stare at the same spot knock over christmas tree hide when guests come over.
Cat snacks cough furball but leave hair everywhere, yet chew iPad power cord scream at teh bath or then cats take over the world. Eat grass, throw it back up i am the best and spread kitty litter all over house yet all of a sudden cat goes crazy. Caticus cuteicus my left donut is missing, as is my right. Pooping rainbow while flying in a toasted bread costume in space shake treat bag.


The ancient Japanese have been devising new ways to fold paper for centuries. In a practice called Origami, the far east has been new paper shapes for generations. Now, as computer graphics technology has become more advanced, we have been able to create more complex shapes than ever. Curved and multi-faceted faces through folds can be procedurally generated by advanced computer imaging techniques. However, these shapes are often difficult to fold and require many different folds simultaneously. To solve this problem, we have engineered a system to use strings to make these folds easier to accomplish.
With this new technology, shapes that were previously out of reach can now be folded. Applications in fabrication and product design can lead to more complex shapes created with fewer materials. Structurally sound fabrication can now be accomplished in new ways with more effecient folding techniques. Natural motion and movement can be simulated with real materials using the folding process and string method.
references


Southbound US 41 Caloosahatchee Bridge is reopened to traffic
by WFTX Digital TeamThe Fort Myers Police Department says all lanes on the Caloosahatchee Bridge have reopened after a rollover crash on Saturday caused all lanes to close.
The Fort Myers Police Department was on the scene of a rollover crash on Southbound US 41. The crash caused all lanes to close on the Caloosahatchee bridge leading into downtown Fort Myers. The southbound lanes are completely closed to traffic, and drivers were advised to use the Edison Bridge as an alternate route.
Police say there were minor injuries. No further information is available at this time.