ShellCheck هي أداة GPLv3 تقدم تحذيرات واقتراحات لنصوص bash/sh Shell:
أهداف ShellCheck هي
للإشارة إلى مشكلات بناء الجملة النموذجية للمبتدئين وتوضيحها والتي تتسبب في قيام الصدفة بإعطاء رسائل خطأ مشفرة.
للإشارة إلى المشكلات الدلالية النموذجية ذات المستوى المتوسط وتوضيحها والتي تتسبب في تصرف الصدفة بشكل غريب وغير بديهي.
للإشارة إلى التحذيرات الدقيقة والحالات الزاوية والمزالق التي قد تتسبب في فشل البرنامج النصي الذي يعمل للمستخدم المتقدم في ظل الظروف المستقبلية.
راجع معرض التعليمات البرمجية السيئة للحصول على أمثلة لما يمكن أن يساعدك ShellCheck في تحديده!
هناك عدد من الطرق لاستخدام ShellCheck!
الصق برنامج شل النصي على https://www.shellcheck.net للحصول على تعليقات فورية.
تتم مزامنة ShellCheck.net دائمًا مع أحدث التزام من git، وهي الطريقة الأسهل لتجربة ShellCheck. أخبر أصدقائك!
قم بتشغيل shellcheck yourscript
في جهازك الطرفي للحصول على إخراج فوري، كما هو موضح أعلاه.
يمكنك رؤية اقتراحات ShellCheck مباشرة في مجموعة متنوعة من المحررين.
.
.
سامية، من خلال SublimeLinter.
تحرير النجم النابض (Atom سابقًا)، من خلال النجم النابض linter-shellcheck.
VSCode، من خلال vscode-shellcheck.
معظم المحررين الآخرين، من خلال التوافق مع الأخطاء في دول مجلس التعاون الخليجي.
على الرغم من أن ShellCheck مخصص في الغالب للاستخدام التفاعلي، إلا أنه يمكن إضافته بسهولة إلى الإصدارات أو مجموعات الاختبار. إنه يستخدم رموز الخروج بشكل أساسي، لذا يمكنك فقط إضافة أمر shellcheck
كجزء من العملية.
على سبيل المثال، في ملف Makefile:
check-scripts :
# Fail if any of these files have warnings
shellcheck myscripts/*.sh
أو في ملف Travis CI .travis.yml
:
script :
# Fail if any of these files have warnings
- shellcheck myscripts/*.sh
الخدمات والأنظمة الأساسية التي تم تثبيت ShellCheck عليها مسبقًا وجاهزة للاستخدام:
تتيح لك معظم الخدمات الأخرى، بما في ذلك GitLab، تثبيت ShellCheck بنفسك، إما من خلال مدير حزم النظام (راجع التثبيت)، أو عن طريق تنزيل إصدار ثنائي وتفريغه.
إنها فكرة جيدة أن تقوم بتثبيت إصدار ShellCheck محدد يدويًا بغض النظر. يؤدي هذا إلى تجنب أي فواصل بناء مفاجئة عند نشر إصدار جديد بتحذيرات جديدة.
بالنسبة للتصفية أو إعداد التقارير المخصصة، يمكن لـ ShellCheck إخراج JSON بسيط وXML متوافق مع CheckStyle وتحذيرات متوافقة مع دول مجلس التعاون الخليجي بالإضافة إلى نص يمكن قراءته بواسطة الإنسان (مع أو بدون ألوان ANSI). راجع صفحة wiki الخاصة بالتكامل لمزيد من الوثائق.
أسهل طريقة لتثبيت ShellCheck محليًا هي من خلال مدير الحزم لديك.
على الأنظمة التي تحتوي على Cabal (يتم التثبيت على ~/.cabal/bin
):
cabal update
cabal install ShellCheck
على الأنظمة التي تحتوي على Stack (يتم التثبيت على ~/.local/bin
):
stack update
stack install ShellCheck
في التوزيعات المبنية على دبيان:
sudo apt install shellcheck
في التوزيعات المستندة إلى Arch Linux:
pacman -S shellcheck
أو احصل على صندوق فحص Shell المجاني من AUR.
على التوزيعات القائمة على Gentoo:
emerge --ask shellcheck
في التوزيعات المستندة إلى EPEL:
sudo yum -y install epel-release
sudo yum install ShellCheck
على التوزيعات المعتمدة على فيدورا:
dnf install ShellCheck
على فري بي إس دي:
pkg install hs-ShellCheck
على نظام التشغيل macOS (OS X) مع Homebrew:
brew install shellcheck
أو مع منافذ ماك:
sudo port install shellcheck
على برنامج OpenBSD:
pkg_add shellcheck
على أوبن سوزي
zypper in ShellCheck
أو استخدم OneClickInstall - https://software.opensuse.org/package/ShellCheck
على سولوس:
eopkg install shellcheck
على نظام التشغيل Windows (عبر الشوكولاتة):
C: > choco install shellcheck
أو Windows (عبر Winget):
C: > winget install --id koalaman.shellcheck
أو ويندوز (عبر المجرفة):
C: > scoop install shellcheck
من كوندا فورج:
conda install -c conda-forge shellcheck
من متجر سناب:
snap install --channel=edge shellcheck
من دوكر هب:
docker run --rm -v " $PWD :/mnt " koalaman/shellcheck:stable myscript
# Or :v0.4.7 for that version, or :latest for daily builds
أو استخدم koalaman/shellcheck-alpine
إذا كنت تريد توسيع صورة أكبر تعتمد على Alpine Linux. إنها تعمل تمامًا مثل صورة جبال الألب العادية، ولكنها تحتوي على نظام فحص الصدفة المثبت مسبقًا.
باستخدام مدير الحزم nix:
nix-env -iA nixpkgs.shellcheck
باستخدام مدير الحزم Flox
flox install shellcheck
وبدلاً من ذلك، يمكنك تنزيل الثنائيات المجمعة مسبقًا لأحدث إصدار هنا:
أو راجع إصدارات GitHub للاطلاع على الإصدارات الأخرى (بما في ذلك أحدث إصدار تعريفي لإصدارات git اليومية).
لا توجد حاليًا أي ثنائيات رسمية لـ Apple Silicon، ولكن تتوفر إصدارات خارجية عبر ShellCheck لـ Visual Studio Code.
تأتي حزم التوزيعة بالفعل مع صفحة man
. إذا كنت تقوم بالإنشاء من المصدر، فيمكن تثبيته باستخدام:
pandoc -s -f markdown-smart -t man shellcheck.1.md -o shellcheck.1
sudo mv shellcheck.1 /usr/share/man/man1
لتشغيل ShellCheck عبر الالتزام المسبق، أضف الرابط إلى .pre-commit-config.yaml
:
repos:
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.7.2
hooks:
- id: shellcheck
# args: ["--severity=warning"] # Optionally only show errors and warnings
قام Travis CI الآن بدمج ShellCheck افتراضيًا، لذلك لا تحتاج إلى تثبيته يدويًا.
إذا كنت لا تزال ترغب في القيام بذلك من أجل الترقية في وقت فراغك أو التأكد من أنك تستخدم الإصدار الأحدث، فاتبع الخطوات أدناه لتثبيت إصدار ثنائي.
تأتي الثنائيات المترجمة مسبقًا في ملفات tar.xz
لفك ضغطها، تأكد من تثبيت xz
. على Debian/Ubuntu/Mint، يمكنك apt install xz-utils
. على Redhat/Fedora/CentOS، yum -y install xz
.
قد يقوم المثبت البسيط بشيء مثل:
scversion= " stable " # or "v0.4.7", or "latest"
wget -qO- " https://github.com/koalaman/shellcheck/releases/download/ ${scversion?} /shellcheck- ${scversion?} .linux.x86_64.tar.xz " | tar -xJv
cp " shellcheck- ${scversion} /shellcheck " /usr/bin/
shellcheck --version
يصف هذا القسم كيفية إنشاء ShellCheck من الدليل المصدر. تمت كتابة ShellCheck بلغة Haskell ويتطلب 2 غيغابايت من ذاكرة الوصول العشوائي لتجميعه.
تم تصميم ShellCheck وتعبئته باستخدام Cabal. قم بتثبيت الحزمة cabal-install
من مدير الحزم في نظامك (على سبيل المثال apt-get
أو brew
أو emerge
أو yum
أو zypper
).
على نظام التشغيل macOS (OS X)، يمكنك إجراء تثبيت سريع لبرنامج Cabal باستخدام Brew، والذي يستغرق بضع دقائق بدلاً من أكثر من 30 دقيقة إذا حاولت تجميعه من المصدر.
$ brew install cabal-install
في MacPorts، يُطلق على الحزمة اسم hs-cabal-install
بدلاً من ذلك، بينما يجب على مستخدمي Windows الأصليين تثبيت أحدث إصدار من نظام Haskell الأساسي من https://www.haskell.org/platform/
تحقق من تثبيت cabal
وقم بتحديث قائمة التبعيات الخاصة به
$ cabal update
git clone
هذا المستودع، وأدخل cd
إلى دليل مصدر ShellCheck لإنشاء/تثبيت:
$ cabal install
سيؤدي هذا إلى تجميع ShellCheck وتثبيته في دليل ~/.cabal/bin
الخاص بك.
أضف هذا الدليل إلى PATH
الخاص بك (للباش، أضف هذا إلى ~/.bashrc
):
export PATH= " $HOME /.cabal/bin: $PATH "
قم بتسجيل الخروج ثم الدخول مرة أخرى، وتأكد من إعداد PATH بشكل صحيح:
$ which shellcheck
~ /.cabal/bin/shellcheck
في نظام التشغيل Windows الأصلي، يجب أن يكون PATH
قد تم إعداده بالفعل، ولكن قد يستخدم النظام صفحة رموز قديمة. في cmd.exe
و powershell.exe
وPowershell ISE، تأكد من استخدام خط TrueType، وليس خط Raster، وقم بتعيين صفحة الرموز النشطة على UTF-8 (65001) باستخدام chcp
:
chcp 65001
في Powershell ISE، قد تحتاج إلى تحديث ترميز الإخراج بشكل إضافي:
[ Console ]::OutputEncoding = [ System.Text.Encoding ]::UTF8
لتشغيل مجموعة اختبار الوحدة:
$ cabal test
إذن ما نوع الأشياء التي تبحث عنها ShellCheck؟ فيما يلي قائمة غير كاملة بالمشكلات المكتشفة.
يمكن لـ ShellCheck التعرف على عدة أنواع من الاقتباس غير الصحيح:
echo $1 # Unquoted variables
find . -name * .ogg # Unquoted find/grep patterns
rm " ~/my file.txt " # Quoted tilde expansion
v= ' --verbose="true" ' ; cmd $v # Literal quotes in variables
for f in " *.ogg " # Incorrectly quoted 'for' loops
touch $@ # Unquoted $@
echo ' Don ' t forget to restart ! ' # Singlequote closed by apostrophe
echo ' Don ' t try this at home ' # Attempting to escape ' in ' '
echo ' Path is $PATH ' # Variables in single quotes
trap " echo Took ${SECONDS} s " 0 # Prematurely expanded trap
unset var[i] # Array index treated as glob
يمكن لـ ShellCheck التعرف على العديد من أنواع بيانات الاختبار غير الصحيحة.
[[ n != 0 ]] # Constant test expressions
[[ -e * .mpg ]] # Existence checks of globs
[[ $foo == 0 ]] # Always true due to missing spaces
[[ -n " $foo " ]] # Always true due to literals
[[ $foo =~ " fo+ " ]] # Quoted regex in =~
[ foo =~ re ] # Unsupported [ ] operators
[ $1 -eq " shellcheck " ] # Numerical comparison of strings
[ $n && $m ] # && in [ .. ]
[ grep -q foo file ] # Command without $(..)
[[ " $$ file " == * .jpg ]] # Comparisons that can't succeed
(( 1 - lt 2 )) # Using test operators in ((..))
[ x ] & [ y ] | [ z ] # Accidental backgrounding and piping
يمكن لـ ShellCheck التعرف على الحالات التي يتم فيها استخدام الأوامر بشكل غير صحيح:
grep ' *foo* ' file # Globs in regex contexts
find . -exec foo {} && bar {} ; # Prematurely terminated find -exec
sudo echo ' Var=42 ' > /etc/profile # Redirecting sudo
time --format=%s sleep 10 # Passing time(1) flags to time builtin
while read h ; do ssh " $h " uptime # Commands eating while loop input
alias archive= ' mv $1 /backup ' # Defining aliases with arguments
tr -cd ' [a-zA-Z0-9] ' # [] around ranges in tr
exec foo ; echo " Done! " # Misused 'exec'
find -name * .bak -o -name * ~ -delete # Implicit precedence in find
# find . -exec foo > bar ; # Redirections in find
f () { whoami ; }; sudo f # External use of internal functions
يتعرف ShellCheck على العديد من الأخطاء النحوية الشائعة للمبتدئين:
var = 42 # Spaces around = in assignments
$foo =42 # $ in assignments
for $var in * ; do ... # $ in for loop variables
var $n = " Hello " # Wrong indirect assignment
echo ${var $n } # Wrong indirect reference
var=(1, 2, 3) # Comma separated arrays
array=( [index] = value ) # Incorrect index initialization
echo $var [14] # Missing {} in array references
echo " Argument 10 is $1 0 " # Positional parameter misreference
if $( myfunction ) ; then .. ; fi # Wrapping commands in $()
else if othercondition ; then .. # Using 'else if'
f ; f () { echo " hello world; } # Using function before definition
[ false ] # 'false' being true
if ( -f file ) # Using (..) instead of test
بإمكان ShellCheck تقديم اقتراحات لتحسين الأسلوب:
[[ -z $( find /tmp | grep mpg ) ]] # Use grep -q instead
a >> log ; b >> log ; c >> log # Use a redirection block instead
echo " The time is ` date ` " # Use $() instead
cd dir ; process * ; cd .. ; # Use subshells instead
echo $[1+2] # Use standard $((..)) instead of old $[]
echo $(( $RANDOM % 6 )) # Don't use $ on variables in $((..))
echo " $( date ) " # Useless use of echo
cat file | grep foo # Useless use of cat
يمكن لـ ShellCheck التعرف على المشكلات المتعلقة بالبيانات والكتابة:
args= " $@ " # Assigning arrays to strings
files=(foo bar) ; echo " $files " # Referencing arrays as strings
declare -A arr=(foo bar) # Associative arrays without index
printf " %sn " " Arguments: $@ . " # Concatenating strings and arrays
[[ $# > 2 ]] # Comparing numbers as strings
var=World ; echo " Hello " var # Unused lowercase variables
echo " Hello $name " # Unassigned lowercase variables
cmd | read bar ; echo $bar # Assignments in subshells
cat foo | cp bar # Piping to commands that don't read
printf ' %s: %sn ' foo # Mismatches in printf argument count
eval " ${array[@]} " # Lost word boundaries in array eval
for i in " ${x[@]} " ; do ${x[$i]} # Using array value as key
يمكن لـ ShellCheck تقديم اقتراحات لتحسين قوة البرنامج النصي:
rm -rf " $STEAMROOT / " * # Catastrophic rm
touch ./-l ; ls * # Globs that could become options
find . -exec sh -c ' a && b {} ' ; # Find -exec shell injection
printf " Hello $name " # Variables in printf format
for f in $( ls * .txt ) ; do # Iterating over ls output
export MYVAR= $( cmd ) # Masked exit codes
case $version in 2. * ) : ;; 2.6. * ) # Shadowed case branches
سوف يحذرك ShellCheck عند استخدام ميزات غير مدعومة من قبل shebang. على سبيل المثال، إذا قمت بتعيين shebang على #!/bin/sh
، فسوف يحذر ShellCheck من مشكلات قابلية النقل المشابهة لـ checkbashisms
:
echo {1.. $n } # Works in ksh, but not bash/dash/sh
echo {1..10} # Works in ksh and bash, but not dash/sh
echo -n 42 # Works in ksh, bash and dash, undefined in sh
expr match str regex # Unportable alias for `expr str : regex`
trap ' exit 42 ' sigint # Unportable signal spec
cmd & > file # Unportable redirection operator
read foo < /dev/tcp/host/22 # Unportable intercepted files
foo-bar () { .. ; } # Undefined/unsupported function name
[ $UID = 0 ] # Variable undefined in dash/sh
local var=value # local is undefined in sh
time sleep 1 | sleep 5 # Undefined uses of 'time'
يتعرف ShellCheck على مجموعة من المشكلات الأخرى:
PS1= ' e[0;32m$e[0m ' # PS1 colors not in [..]
PATH= " $PATH :~/bin " # Literal tilde in $PATH
rm “file” # Unicode quotes
echo " Hello world " # Carriage return / DOS line endings
echo hello # Trailing spaces after
var=42 echo $var # Expansion of inlined environment
! # bin/bash -x -e # Common shebang errors
echo $(( n / 180 * 100 )) # Unnecessary loss of precision
ls * [:digit:].txt # Bad character class globs
sed ' s/foo/bar/ ' file > file # Redirecting to input
var2= $var2 # Variable assigned to itself
[ x $var = xval ] # Antiquated x-comparisons
ls () { ls -l " $@ " ; } # Infinitely recursive wrapper
alias ls= ' ls -l ' ; ls foo # Alias used before it takes effect
for x ; do for x ; do # Nested loop uses same variable
while getopts " a " f ; do case $f in " b " ) # Unhandled getopts flags
في البداية كنت مثل "shellcheck رائع" ولكن بعد ذلك كنت مثل "هل ما زلنا نستخدم bash"
ألكسندر تاراسكوف على تويتر
يمكن تجاهل المشكلات عبر المتغير البيئي أو سطر الأوامر بشكل فردي أو عالمي داخل الملف:
https://github.com/koalaman/shellcheck/wiki/Ignore
الرجاء استخدام أداة تعقب مشكلات GitHub لمعرفة أي أخطاء أو اقتراحات للميزات:
https://github.com/koalaman/shellcheck/issues
يرجى إرسال التصحيحات إلى التعليمات البرمجية أو الوثائق حسب طلبات سحب GitHub! قم بمراجعة DevGuide على ShellCheck Wiki.
يجب أن تكون المساهمات مرخصة بموجب GNU GPLv3. يحتفظ المساهم بحقوق الطبع والنشر.
تم ترخيص ShellCheck بموجب رخصة GNU العامة، الإصدار 3. تم تضمين نسخة من هذا الترخيص في ملف LICENSE.
حقوق الطبع والنشر 2012-2019، Vidar 'koala_man' Holen والمساهمين.
سعيد شلفحص!