diff --git a/.ci/scripts/test_export_data_command.sh b/.ci/scripts/test_export_data_command.sh
index 468a9d61ffc62bbd88a4fe954f3015d87439739b..ab96387a0aef31e87f96003a1c75eb02002dff24 100755
--- a/.ci/scripts/test_export_data_command.sh
+++ b/.ci/scripts/test_export_data_command.sh
@@ -3,7 +3,7 @@
 # Test for the export-data admin command against sqlite and postgres
 
 set -xe
-cd "`dirname "$0"`/../.."
+cd "$(dirname "$0")/../.."
 
 echo "--- Install dependencies"
 
diff --git a/.ci/scripts/test_synapse_port_db.sh b/.ci/scripts/test_synapse_port_db.sh
index 3926a17eabdc62cfc381dd2481db1a3211cc1428..797904e64ca5325fe0b6ee1d8eb235ee923fdd92 100755
--- a/.ci/scripts/test_synapse_port_db.sh
+++ b/.ci/scripts/test_synapse_port_db.sh
@@ -7,7 +7,7 @@
 
 
 set -xe
-cd "`dirname "$0"`/../.."
+cd "$(dirname "$0")/../.."
 
 echo "--- Install dependencies"
 
diff --git a/debian/build_virtualenv b/debian/build_virtualenv
index 575c2e016dd97b378f41bacf982c63b5bd462c15..3097371d59d8c2070e1a00fc1821a74283375dfe 100755
--- a/debian/build_virtualenv
+++ b/debian/build_virtualenv
@@ -15,7 +15,7 @@ export DH_VIRTUALENV_INSTALL_ROOT=/opt/venvs
 # python won't look in the right directory. At least this way, the error will
 # be a *bit* more obvious.
 #
-SNAKE=`readlink -e /usr/bin/python3`
+SNAKE=$(readlink -e /usr/bin/python3)
 
 # try to set the CFLAGS so any compiled C extensions are compiled with the most
 # generic as possible x64 instructions, so that compiling it on a new Intel chip
@@ -24,7 +24,7 @@ SNAKE=`readlink -e /usr/bin/python3`
 # TODO: add similar things for non-amd64, or figure out a more generic way to
 # do this.
 
-case `dpkg-architecture -q DEB_HOST_ARCH` in
+case $(dpkg-architecture -q DEB_HOST_ARCH) in
     amd64)
         export CFLAGS=-march=x86-64
         ;;
@@ -56,7 +56,7 @@ case "$DEB_BUILD_OPTIONS" in
     *)
         # Copy tests to a temporary directory so that we can put them on the
         # PYTHONPATH without putting the uninstalled synapse on the pythonpath.
-        tmpdir=`mktemp -d`
+        tmpdir=$(mktemp -d)
         trap 'rm -r $tmpdir' EXIT
 
         cp -r tests "$tmpdir"
@@ -98,7 +98,7 @@ esac
         --output-file="${PACKAGE_BUILD_DIR}/etc/matrix-synapse/log.yaml"
 
 # add a dependency on the right version of python to substvars.
-PYPKG=`basename "$SNAKE"`
+PYPKG=$(basename "$SNAKE")
 echo "synapse:pydepends=$PYPKG" >> debian/matrix-synapse-py3.substvars
 
 
diff --git a/debian/test/provision.sh b/debian/test/provision.sh
index 8567b146ad2ae7c2a4531ed2738228906fc76a63..55d7b8e03a1ba20df4a2514e10396e0487b92690 100644
--- a/debian/test/provision.sh
+++ b/debian/test/provision.sh
@@ -10,7 +10,7 @@ set -e
 apt-get update
 apt-get install -y lsb-release
 
-deb=`find /debs -name "matrix-synapse-py3_*+$(lsb_release -cs)*.deb" | sort | tail -n1`
+deb=$(find /debs -name "matrix-synapse-py3_*+$(lsb_release -cs)*.deb" | sort | tail -n1)
 
 debconf-set-selections <<EOF
 matrix-synapse matrix-synapse/report-stats boolean false
diff --git a/docker/build_debian.sh b/docker/build_debian.sh
index 32ad07a0cce4a3349ba3773bee33f43925a1bb05..9eae38af9191ed1b5ae89539f15a93a7d40b2f25 100644
--- a/docker/build_debian.sh
+++ b/docker/build_debian.sh
@@ -5,7 +5,7 @@
 set -ex
 
 # Get the codename from distro env
-DIST=`cut -d ':' -f2 <<< "${distro:?}"`
+DIST=$(cut -d ':' -f2 <<< "${distro:?}")
 
 # we get a read-only copy of the source: make a writeable copy
 cp -aT /synapse/source /synapse/build
@@ -17,7 +17,7 @@ cd /synapse/build
 # Section to determine which "component" it should go into (see
 # https://manpages.debian.org/stretch/reprepro/reprepro.1.en.html#GUESSING)
 
-DEB_VERSION=`dpkg-parsechangelog -SVersion`
+DEB_VERSION=$(dpkg-parsechangelog -SVersion)
 case $DEB_VERSION in
     *~rc*|*~a*|*~b*|*~c*)
         sed -ie '/^Section:/c\Section: prerelease' debian/control
diff --git a/scripts-dev/check-newsfragment b/scripts-dev/check-newsfragment
index 5fc68e321322f3befccfdb4bc2b1615550d7c18f..af4de345df572ec46cda3d921940b6a92e58a7a7 100755
--- a/scripts-dev/check-newsfragment
+++ b/scripts-dev/check-newsfragment
@@ -42,9 +42,9 @@ echo "--------------------------"
 echo
 
 matched=0
-for f in `git diff --name-only FETCH_HEAD... -- changelog.d`; do
+for f in $(git diff --name-only FETCH_HEAD... -- changelog.d); do
     # check that any modified newsfiles on this branch end with a full stop.
-    lastchar=`tr -d '\n' < "$f" | tail -c 1`
+    lastchar=$(tr -d '\n' < "$f" | tail -c 1)
     if [ "$lastchar" != '.' ] && [ "$lastchar" != '!' ]; then
         echo -e "\e[31mERROR: newsfragment $f does not end with a '.' or '!'\e[39m" >&2
         echo -e "$CONTRIBUTING_GUIDE_TEXT" >&2
diff --git a/scripts-dev/check_line_terminators.sh b/scripts-dev/check_line_terminators.sh
index b48fb88b077c7a5c23782f39e4447a7cfcb416cb..fffa24e01e43ef9801ca25e7203fb89edbcc4743 100755
--- a/scripts-dev/check_line_terminators.sh
+++ b/scripts-dev/check_line_terminators.sh
@@ -25,7 +25,7 @@
 # terminators are found, 0 otherwise.
 
 # cd to the root of the repository
-cd "`dirname "$0"`/.." || exit
+cd "$(dirname "$0")/.." || exit
 
 # Find and print files with non-unix line terminators
 if find . -path './.git/*' -prune -o -type f -print0 | xargs -0 grep -I -l $'\r$'; then
diff --git a/scripts-dev/config-lint.sh b/scripts-dev/config-lint.sh
index 7fb6ab68ef18c34750543b97ae3b58213da55ac2..6ce030b819d6e6809fdb050c31f5e88f78bb83c3 100755
--- a/scripts-dev/config-lint.sh
+++ b/scripts-dev/config-lint.sh
@@ -3,7 +3,7 @@
 # Exits with 0 if there are no problems, or another code otherwise.
 
 # cd to the root of the repository
-cd "`dirname "$0"`/.." || exit
+cd "$(dirname "$0")/.." || exit
 
 # Restore backup of sample config upon script exit
 trap "mv docs/sample_config.yaml.bak docs/sample_config.yaml" EXIT
diff --git a/scripts-dev/generate_sample_config b/scripts-dev/generate_sample_config
index 69d0b632df8d4dbcf022b80c821d02ac310bac27..4cd1d1d5b829d7029b5741a71653ae4a3ce81504 100755
--- a/scripts-dev/generate_sample_config
+++ b/scripts-dev/generate_sample_config
@@ -4,7 +4,7 @@
 
 set -e
 
-cd "`dirname "$0"`/.."
+cd "$(dirname "$0")/.."
 
 SAMPLE_CONFIG="docs/sample_config.yaml"
 SAMPLE_LOG_CONFIG="docs/sample_log_config.yaml"
diff --git a/scripts-dev/next_github_number.sh b/scripts-dev/next_github_number.sh
index 00e9b145698638acf599d00f756fe2831c2162ac..5ecd515127c7172b7dca1e08df11a9d4e67d6722 100755
--- a/scripts-dev/next_github_number.sh
+++ b/scripts-dev/next_github_number.sh
@@ -4,6 +4,6 @@ set -e
 
 # Fetch the current GitHub issue number, add one to it -- presto! The likely
 # next PR number.
-CURRENT_NUMBER=`curl -s "https://api.github.com/repos/matrix-org/synapse/issues?state=all&per_page=1" | jq -r ".[0].number"`
+CURRENT_NUMBER=$(curl -s "https://api.github.com/repos/matrix-org/synapse/issues?state=all&per_page=1" | jq -r ".[0].number")
 CURRENT_NUMBER=$((CURRENT_NUMBER+1))
 echo $CURRENT_NUMBER