Scientific Computing

Detect Bash, zsh or other shell

A 5-way shell detect script can detect bash, csh, dash, ksh, or zsh. However, often we simply want to detect if the shell is Bash or something else. For example, in a Bash-dependent script we may thereby stop and recommend the user use Bash to avoid needing to test across numerous shells. There are a number of pitfalls in detecting a shell type so this method is not completely robust either, but has worked. The key to this technique is that while different shells have distinct “if-else” syntax, most shells have “case-esac”.

Not every shell has the "source" command. For example, in Dash (default for Ubuntu "sh"), the "./" is required in front of the filename.

. ./not_bash.sh
view raw README.md hosted with ❤ by GitHub
# source it or copy it into your script to avoid invoking a different shell. That's why there's no shebang.
case "$(type declare)" in
"declare is a shell builtin") echo bash;;
"declare is a reserved word") echo zsh;;
esac
view raw bash_or_zsh.sh hosted with ❤ by GitHub
# source it or copy it into your script to avoid invoking a different shell. That's why there's no shebang.
case "$(type declare)" in
"declare is a shell builtin") ;;
*) echo "Please use Bash shell"; return 1;;
esac
view raw not_bash.sh hosted with ❤ by GitHub

CMake script relocate

When relocating / moving / renaming a CMake script within a project, it may be desired to leave a placeholder at the original script location until users know to use the new script path in the project. Many CMake scripts call other scripts in the project. In general, CMake scripts should use absolute paths, except for install() parameters. That is, CMake scripts should generally start file paths with CMake built-in absolute paths like CMAKE_CURRENT_LIST_DIR and CMAKE_CURRENT_FUNCTION_LIST_DIR. If the script directory is changed, the script references to paths within the project will of course also need to be changed.

Legacy users may take a while to start calling the CMake script at the new location. Note that making a softlink will NOT work in general because the path references would be from the placeholder script location, which in general is distinct from the new script location. To bridge this UX gap, create a trivial one-line script at the original script path like:

include(${CMAKE_CURRENT_LIST_DIR}/../path/to/new-script.cmake)

ATLAS build questions

ATLAS gives a higher performance subset of LAPACK. ATLAS was last released in 2016, and has problems building on modern computers. Debian and Ubuntu have numerous patches needed to build ATLAS. Thus we don’t currently have an easy CMake script to build ATLAS as we do for other popular libraries like LAPACK, Scalapack, METIS and Scotch.

An attempt to build ATLAS via CMake that fails due to ATLAS Autotools issues:

project(atlas LANGUAGES C)

include(ExternalProject)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

set_property(DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED true)
# don't recheck for updates to the Git repo at subsequent CMake reconfigure

set(atlas_url https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/atlas/3.10.3-10ubuntu3/atlas_3.10.3-10ubuntu3.debian.tar.xz)

find_package(Autotools REQUIRED)

ExternalProject_Add(atlas
URL ${atlas_url}
CONFIGURE_HANDLED_BY_BUILD true
CONFIGURE_COMMAND <SOURCE_DIR>/configure
BUILD_COMMAND ${MAKE_EXECUTABLE} -j
INSTALL_COMMAND ${MAKE_EXECUTABLE} install
)

Aspell for Windows

The native Windows Aspell port is no longer supported. Instead, use Aspell in Windows via Windows Subsystem for Linux. Install Aspell in Windows Subsystem for Linux:

wsl apt install aspell

Then check spelling of a file like:

wsl aspell -c myfile.txt

Note: don’t include the prefix .\ in the file name, as that will not work in WSL.


Alernatively, MSYS2 can provide Aspell in Windows by installing packages

mingw-w64-ucrt-x86_64-aspell
mingw-w64-ucrt-x86_64-aspell-en

Related: Aspell don’t backup Related: Aspell user dictionary location

Git set executable file permission on Windows

When interacting between Windows and Unix filesystems using Git, setting a file to be executable takes a particular Git command from the Windows computer. With standalone Unix systems, just chmod +x myfile.sh is tracked by Git. However, with Windows Subsystem for Linux or Cygwin, this chmod +x change is not tracked if the file resides on a Windows filesystem and not within the WSL internal filesystem.

Windows file mode permission for executable aren’t as trivial as Unix-like chmod. Unix-like file systems such as Linux and macOS need the executable bit set correctly to execute shell scripts and binary executables as expected. On Unix-like file systems, Git propagates the executable permission of files.

To add executable permission on Windows and for all other systems, use Git command:

git update-index --chmod=+x /path/to/exe

To remove executable permission on Windows and for all other systems, use Git command:

git update-index --chmod=-x /path/to/exe

Verify the change to executable permission by:

git status --porcelain=2

which will have output including:

1 M. N… 100644 100755 100755 … /path/to/exe

Measure joystick input lag on PC

Measuring controller / joystick input lag to a computer is not as trivial as one might think. We encourage at least skimming the references below, especially the Lagmeter readme to get background. In short, take a video camera or smartphone capable of 60 frames/second or faster and use an LED wired to the joystick input and video it and the computer display while pressing a button. Video display lag (put the monitor in “game mode” if available) and USB polling cadence are two of several significant factors in input lag. In difficult absolute measurement scenarios such as this, where so many confounding factors are present, a more useful metric may be relative delay measurements, for example wired vs. wireless controllers.

References:

curl build native Windows Schannel

curl is a universal command line tool for network data transfer. Build curl from source on Windows including native TLS support with Visual Studio and CMake. No external libraries are required for SSL using curl native Windows Schannel. The build is done “static” to avoid the hassle of DLL path.

cmake -DCURL_USE_SCHANNEL=on -DBUILD_SHARED_LIBS=off -DCMAKE_C_COMPILER=cl -Bbuild

cmake --build build --config Release

Test the standalone “curl.exe” like:

build/src/Release/curl.exe -L https://hsts.badssl.com/

curl Schannel TLS 1.3 on Windows

We helped discover a curl bug when using native Schannel TLS 1.3 support on Windows for curl 7.85 and 7.86. The symptoms include that downloads may fail on Windows 11 with TLS 1.3 enabled on HTTPS or other TLS 1.3 server downloads. The bug is revealed when building curl on Windows using Schannel. We first observed this in CMake 3.25.0-rc3,rc4 that use vendored curl 7.86.

rclone for Google Drive and Dropbox

rclone seamlessly connects to remote cloud storage for cloud storage services including Google Shared Drive, Dropbox, Microsoft OneDrive and many more providers. The rclone CLI is easier than rsync. rclone works with encrypted filesystems.

Setup Rclone:

  • Linux: winget install Rclone.Rclone
  • macOS / Homebrew: brew install rclone
  • Windows: winget install Rclone.Rclone

Add various remote file shares (Google Drive, Dropbox, etc.) by:

rclone config

In these examples, remote is the particular drive name chosen during rclone config.

Tell the location of the Rclone config file by:

rclone config file

Rclone command examples

List remote directories:

rclone lsd remote:

List remote directories under path/to

rclone lsd remote:path/to

List remote files under path/to

rclone ls remote:path/to

Count number of files in path/to

rclone ls remote:path/to | wc -l

copy in rclone by default does not clobber existing remote files, if they haven’t been changed.

Recursively copy local computer ~/path to remote

rclone copy ~/path remote:path -v

Copy only this directory contents ~/path to remote

rclone copy --max-depth 0  ~/path remote:path -v

Using rclone sync requires caution, because sync DELETES files on remote that are not also on local PC!

Sync local computer ~/path to the remote

rclone sync ~/path remote:path -v

Dropbox

Why not use Dropbox’s unofficial dbxcli? At the time of writing, the last release was in 2019 with many unsolved issues.