Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 88 additions & 31 deletions completions/smartctl
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
# bash completion for smartctl(8) -*- shell-script -*-
# Updated for smartmontools 7.5 (released 2025-04-30)

_comp_cmd_smartctl__device()
{
case $cur in
areca* | 3ware* | megaraid* | cciss*)
3ware,* | cciss,* | areca,* | megaraid,*)
_comp_compgen -- -W '${cur%%,*},{0..31}'
;;
hpt*)
aacraid,*)
_comp_compgen -- -W 'aacraid,{0..1},{0..1},{0..7}'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't specific to this PR but also applies to existing completions for hpt,*, but I'm wondering if it is possible to let the user input each section (separated by commas) incrementally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you point to an example in another completion file?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1425 (comment)

By "incrementally", I mean that, as you did in _comp_cmd_smartctl__vendorattribute, it first generate the completions "${cur%,*}",{0..1}, when cur starts with aacraid, but without any additional comma. When there is already aacraid,[01], in the command line, it generates the next completions "${cur%,*}",{0..1},. When there is aacraid,[01],[01], in the command line, it generates the next completions "${cur%,*}",{0..7},.

;;
hpt,*)
_comp_compgen -- -W 'hpt,{1..4}/{1..8} hpt,{1..4}/{1..8}/{1..5}'
;;
sssraid,*)
_comp_compgen -- -W 'sssraid,{0..1},{0..31}'
;;
jmb39x,* | jmb39x-q,* | jmb39x-q2,* | jms56x,*)
_comp_compgen -- -W '${cur%%,*},{0..4}'
;;
*)
_comp_compgen -- -W 'ata scsi sat usbcypress usbjmicron usbsunplus
marvell areca 3ware hpt megaraid cciss auto test'
case "${COMPREPLY[@]}" in
areca | 3ware | hpt | megaraid | cciss)
compopt -o nospace
;;
esac
_comp_compgen -- -W 'auto test ata scsi nvme{,\,}
sat{,\,auto}{,\,12} usb{jmicron,prolific,sunplus}
snt{asmedia,jmicron,realtek}{,/sat} 3ware, aacraid, areca,
cciss, hpt, megaraid, sssraid, jmb39x{,-q,-q2}, jms56x,'
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
;;
esac
}
_comp_cmd_smartctl__test()
{
[[ $cur == @(pending|scttempint|vendor), ]] && return
_comp_compgen -- -W 'offline short long conveyance select, select,redo
select,next afterselect,on afterselect,off pending, scttempint,
vendor,'
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
}
_comp_cmd_smartctl__drivedb()
{
local prefix=
Expand All @@ -38,13 +38,42 @@ _comp_cmd_smartctl__drivedb()
_comp_compgen_filedir h && [[ $prefix ]] &&
_comp_compgen -Rv COMPREPLY -- -P "$prefix" -W '"${COMPREPLY[@]}"'
}
_comp_cmd_smartctl__vendorattribute()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems to try to assist in inputting a number {0..255} by suggesting one digit at a time, but it can be confusing. For example, when $cur is empty, it only lists {1..9} (which is actually merely the first digit of possible numbers {0..255}), but it looks like the accepted number range is {1..9}.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative: Drop the completion of digits and continue completion after -v {1..255}, or -v N, is present:

_comp_cmd_smartctl__vendorattribute()
{
    local fmt
    case $cur in
        [1-9N],*|[1-9][0-9],*|1[0-9][0-9],*|2[0-4][0-9],*|25[0-5],*)
            fmt='raw{8,16,48,56,64},hex{48,56,64},raw24/raw{24,32}'
            fmt+=',msec24hour32,{sec,min,halfmin}2hour,temp10x,tempminmax'
            _comp_compgen -- -W '${cur%%,*},{'"$fmt"'}{,\,,}'
            ;;
        *)
            _comp_compgen -- -W 'N, help'
            ;;
    esac
    [[ ${COMPREPLY-} == *, ]] && compopt -o nospace
}

This would also fix the insertion of a space for ... with menu-complete you mentioned above.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or

             ;;
+        [1-9])
+            _comp_compgen -- -W '{1..255},'
+            ;;
         *)
             _comp_compgen -- -W 'N, help'
             ;;

though 1TAB will surpass the default bind 'set completion-query-items 100'.

{
local fmt
case $cur in
[1-9N],*|[1-9][0-9],*|1[0-9][0-9],*|2[0-4][0-9],*|25[0-5],*)
fmt='raw{8,16,48,56,64},hex{48,56,64},raw24/raw{24,32}'
fmt+=',msec24hour32,{sec,min,halfmin}2hour,temp10x,tempminmax'
_comp_compgen -- -W '${cur%%,*},{'"$fmt"'}{,\,,}'
;;
[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
_comp_compgen -- -W '${cur}, {100..255},'
;;
[1-9])
_comp_compgen -- -W '${cur}, ${cur}{0..9}'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_comp_compgen -- -W '${cur}, ${cur}{0..9}'
_comp_compgen -- -W '"$cur", "$cur"{0..9}'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all uses of $cur within the _comp_compgen -- -W ... parameter or only this one?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All.

;;
*)
_comp_compgen -- -W '{1..9} N, help'
;;
esac
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Doesn't this cause insertion of a space for {1..9} ($cur in *) and ${cur}{0..9} ($cur in [1-9]) with menu-complete, etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Let me re-think this part...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... see new _comp_cmd_smartctl__vendorattribute() below.

}
_comp_cmd_smartctl__set()
{
_comp_compgen -- -W 'aam,{,off} apm,{,off} dsn,{on,off}
lookahead,{on,off} rcache,{on,off} security-freeze standby,{,off,now}
wcache,{on,off} wcache-sct,{ata,on,off}{,\,p}
wcreorder,{on,off}{,\,p} '"$1"
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
}

_comp_cmd_smartctl()
{
local cur prev words cword was_split comp_args
_comp_initialize -s -- "$@" || return

local noargopts='!(-*|*[qdTbrnsoSlvFPBt]*)'
local noargopts='!(-*|*[qdTbrnoSlvFPBtfgs]*)'
# shellcheck disable=SC2254
case $prev in
--quietmode | -${noargopts}q)
Expand All @@ -64,32 +93,34 @@ _comp_cmd_smartctl()
return
;;
--report | -${noargopts}r)
_comp_compgen -- -W 'ioctl ataioctl scsiioctl'
_comp_compgen -- -W '{,ata,scsi,nvme}ioctl{,\,2}'
return
;;
--nocheck | -${noargopts}n)
_comp_compgen -- -W 'never sleep standby idle'
_comp_compgen -- -W 'never sleep{,\,} standby{,\,} idle{,\,}'
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
return
;;
--smart | --offlineauto | --saveauto | -${noargopts}[soS])
--smart | --offlineauto | --saveauto | -${noargopts}[oS])
_comp_compgen -- -W 'on off'
return
;;
--log | -${noargopts}l)
_comp_compgen -- -W 'error selftest selective directory background
sasphy sasphy,reset sataphy sataphy,reset scttemp scttempsts
scttemphist scterc gplog smartlog xerror xselftest'
_comp_compgen -- -W 'background defects{,\,} devstat{,\,}
directory{,\,g,\,s} envrep error farm genstats gplog, nvmelog,
sasphy{,\,reset} sataphy{,\,reset} scterc{,\,,\,p,\,reset}
scttemp{,sts,int\,,hist} selective selftest smartlog, ssd
tapealert tapedevstat xerror{,\,,\,error}
xselftest{,\,,\,selftest} zdevstat'
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
return
;;
--vendorattribute | -${noargopts}v)
_comp_compgen -- -W 'help 9,minutes 9,seconds 9,halfminutes 9,temp
192,emergencyretractcyclect 193,loadunload 194,10xCelsius
194,unknown 198,offlinescanuncsectorct 200,writeerrorcount
201,detectedtacount 220,temp'
_comp_cmd_smartctl__vendorattribute
return
;;
--firmwarebug | -${noargopts}F)
_comp_compgen -- -W 'none samsung samsung2 samsung3 swapid'
_comp_compgen -- -W 'none nologdir samsung{,2,3} swapid xerrorlba'
return
;;
--presets | -${noargopts}P)
Expand All @@ -101,15 +132,41 @@ _comp_cmd_smartctl()
return
;;
--test | -${noargopts}t)
_comp_cmd_smartctl__test
_comp_compgen -- -W 'afterselect,{on,off} conveyance force long
offline pending, scttempint, select,{,redo,next} short vendor,'
[[ ${COMPREPLY-} == *, ]] && compopt -o nospace
return
;;
--format | -${noargopts}f)
_comp_compgen -- -W 'brief hex{,\,id,\,val} old'
return
;;
--get | -${noargopts}g)
_comp_compgen -- -W 'aam all apm dsn lookahead rcache security
wcache{,-sct} wcreorder'
return
;;
--set)
_comp_cmd_smartctl__set ''
return
;;
-${noargopts}s) # -s {on,off}: --smart {on,off}; -s OTHER: --set OTHER
_comp_cmd_smartctl__set 'on off'
return
;;
esac

[[ $was_split ]] && return

if [[ $cur == -* ]]; then
_comp_compgen_help
# _comp_compgen_help # not used because result is incomplete
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to avoid hardcoding as much as possible because a hardcoded list cannot reflect version differences. Couldn't the output of smartctl --help be fixed so that a complete list of options can be extracted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - for the long term as this is already planned for next release. But next release 8.0 will take plenty of time due to planned refactoring and enhancements after we finally moved the project from SF svn to GH three month ago.

So please accept the hardcoding for now to support existing releases.

Please note that the current coverage of options is really outdated. For example the -v, --vendorattribute completions only cover options which are deprecated since I added the more flexible -v ID,RAW_FORMAT,ATTR_NAME syntax in smartmontools 5.39. This version was released in December 2009.

Copy link
Collaborator

@akinomyoga akinomyoga Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm talking about the above line of removing _comp_compgen_help. I'm not talking about the list of possible values for option arguments of each option (though it would be better if the smartctl binary could provide a list of possible values in 8.0). I've checked the output of _comp_compgen_help, and the only missing options are --drivedb, --nocheck, and --set, where the following lines in the output --help seem to fail to be parsed.

  -n MODE[,STATUS[,STATUS2]], --nocheck=MODE[,STATUS[,STATUS2]] (ATA, SCSI)
  -s NAME[,VALUE], --set=NAME[,VALUE]
  -B [+]FILE, --drivedb=[+]FILE                                       (ATA)

This may be fixed at the side of _comp_compgen_help by allowing a wider format of the option argument name at line 1697 of bash_completion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #1430.

_comp_compgen -- -W '--abort --all --attributes --badsum=
--capabilities --captive --device= --drivedb= --firmwarebug=
--format= --get= --health --help --identify{,=} --info --json{,=}
--log= --nocheck= --offlineauto= --presets= --quietmode= --report=
--saveauto= --scan{,-open} --set= --smart= --test= --tolerance=
--vendorattribute= --version --xall -A -B -C -F -H -P -S -T -V -X
-a -b -c -d -f -g -h -i -j -l -n -o -q -r -s -t -v -x'
Comment on lines +168 to +169
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check CONTRIBUTING.md; remove short options that have corresponding long options.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course. Sorry, I missed that note.

[[ ${COMPREPLY-} == *= ]] && compopt -o nospace
else
_comp_compgen -c "${cur:-/dev/}" filedir
Expand Down